/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 (
59
    GitObjectConverter,
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.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
110
def import_git_blob(texts, mapping, path, blob, base_inv, parent_id, 
111
    revision_id, parent_invs, shagitmap, executable):
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.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
120
    # We just have to hope this is indeed utf-8:
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
121
    ie = InventoryFile(file_id, urlutils.basename(path).decode("utf-8"), 
122
        parent_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
123
    ie.text_size = len(blob.data)
124
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
125
    ie.executable = executable
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
126
    # If there were no changes compared to the base inventory, there's no need 
127
    # for a delta
128
    if (file_id in base_inv and 
129
        base_inv[file_id].parent_id == ie.parent_id and
130
        base_inv[file_id].text_sha1 == ie.text_sha1 and
131
        base_inv[file_id].executable == ie.executable):
132
        return []
133
    # Check what revision we should store
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
134
    parent_keys = []
135
    for pinv in parent_invs:
0.200.285 by Jelmer Vernooij
Simplify blob import code.
136
        if not file_id in pinv:
137
            continue
138
        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).
139
            # found a revision in one of the parents to use
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
140
            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).
141
            break
0.200.286 by Jelmer Vernooij
Prevent creating repeated directory texts.
142
        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).
143
    if ie.revision is None:
144
        # Need to store a new revision
145
        ie.revision = revision_id
146
        assert file_id is not None
147
        assert ie.revision is not None
148
        texts.add_lines((file_id, ie.revision), parent_keys,
149
            osutils.split_lines(blob.data))
150
        shagitmap.add_entry(blob.sha().hexdigest(), "blob",
151
            (ie.file_id, ie.revision))
152
    if file_id in base_inv:
153
        old_path = base_inv.id2path(file_id)
154
    else:
155
        old_path = None
156
    return [(old_path, path, file_id, ie)]
0.200.261 by Jelmer Vernooij
More formatting fixes.
157
158
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
159
def import_git_tree(texts, mapping, path, tree, base_inv, parent_id, 
160
    revision_id, parent_invs, shagitmap, lookup_object):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
161
    """Import a git tree object into a bzr repository.
162
0.200.261 by Jelmer Vernooij
More formatting fixes.
163
    :param texts: VersionedFiles object to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
164
    :param path: Path in the tree
165
    :param tree: A git tree object
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
166
    :param base_inv: Base inventory against which to return inventory delta
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
167
    :return: Inventory delta for this subtree
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
168
    """
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
169
    ret = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
170
    file_id = mapping.generate_file_id(path)
0.200.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
171
    # 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).
172
    ie = InventoryDirectory(file_id, urlutils.basename(path.decode("utf-8")), 
173
        parent_id)
174
    if not file_id in base_inv:
175
        # Newly appeared here
176
        ie.revision = revision_id
177
        texts.add_lines((file_id, ie.revision), [], [])
178
        ret.append((None, path, file_id, ie))
179
    else:
180
        # See if this has changed at all
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
181
        try:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
182
            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.
183
        except KeyError:
184
            pass
0.200.288 by Jelmer Vernooij
Add test for init-repo.
185
        else:
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
186
            if base_sha == tree.id:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
187
                # If nothing has changed since the base revision, we're done
188
                return []
189
    # Remember for next time
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
190
    existing_children = set()
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
191
    shagitmap.add_entry(tree.id, "tree", (file_id, revision_id))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
192
    for mode, name, hexsha in tree.entries():
193
        entry_kind = (mode & 0700000) / 0100000
194
        basename = name.decode("utf-8")
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
195
        existing_children.add(basename)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
196
        if path == "":
197
            child_path = name
198
        else:
199
            child_path = urlutils.join(path, name)
0.200.264 by Jelmer Vernooij
Add more tests.
200
        obj = lookup_object(hexsha)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
201
        if entry_kind == 0:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
202
            ret.extend(import_git_tree(texts, mapping, child_path, obj, base_inv, 
203
                file_id, revision_id, parent_invs, shagitmap, lookup_object))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
204
        elif entry_kind == 1:
0.200.159 by Jelmer Vernooij
Fix branch tests.
205
            fs_mode = mode & 0777
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
206
            ret.extend(import_git_blob(texts, mapping, child_path, obj, base_inv, 
207
                file_id, revision_id, parent_invs, shagitmap, 
208
                bool(fs_mode & 0111)))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
209
        else:
210
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
211
    # Remove any children that have disappeared
212
    if file_id in base_inv:
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
213
        deletable = [v for k,v in base_inv[file_id].children.iteritems() if k not in existing_children]
214
        while deletable:
215
            ie = deletable.pop()
216
            ret.append((base_inv.id2path(ie.file_id), None, ie.file_id, None))
217
            if ie.kind == "directory":
218
                deletable.extend(ie.children.values())
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
219
    return ret
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
220
221
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
222
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.
223
        heads, pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
224
    """Import a set of git objects into a bzr repository.
225
226
    :param repo: Bazaar repository
227
    :param mapping: Mapping to use
228
    :param object_iter: Iterator over Git objects.
229
    """
230
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
231
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
232
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
233
    revisions = {}
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
234
    checked = set()
235
    heads = list(heads)
0.200.301 by Jelmer Vernooij
Cache inventories created.
236
    parent_invs_cache = LRUCache(50)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
237
    # Find and convert commit objects
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
238
    while heads:
239
        if pb is not None:
240
            pb.update("finding revisions to fetch", len(graph), None)
241
        head = heads.pop()
242
        assert isinstance(head, str)
243
        o = object_iter[head]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
244
        if isinstance(o, Commit):
245
            rev = mapping.import_commit(o)
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
246
            if repo.has_revision(rev.revision_id):
247
                continue
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
248
            root_trees[rev.revision_id] = o.tree
0.200.158 by Jelmer Vernooij
fetch works \o/
249
            revisions[rev.revision_id] = rev
250
            graph.append((rev.revision_id, rev.parent_ids))
0.200.261 by Jelmer Vernooij
More formatting fixes.
251
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(),
252
                "commit", (rev.revision_id, o._tree))
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
253
            heads.extend([p for p in o.parents if p not in checked])
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
254
        elif isinstance(o, Tag):
255
            heads.append(o.object[1])
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
256
        else:
257
            trace.warning("Unable to import head object %r" % o)
258
        checked.add(head)
0.200.158 by Jelmer Vernooij
fetch works \o/
259
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
260
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
261
    for i, revid in enumerate(topo_sort(graph)):
262
        if pb is not None:
263
            pb.update("fetching revisions", i, len(graph))
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
264
        root_tree = object_iter[root_trees[revid]]
0.200.158 by Jelmer Vernooij
fetch works \o/
265
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
266
        # 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.
267
        # 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.
268
        # path; this may involve adding them more than once.
269
        def lookup_object(sha):
0.200.301 by Jelmer Vernooij
Cache inventories created.
270
            try:
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
271
                return object_iter[sha]
0.200.301 by Jelmer Vernooij
Cache inventories created.
272
            except KeyError:
273
                return target_git_object_retriever[sha]
274
        parent_invs = []
275
        for parent_id in rev.parent_ids:
276
            try:
277
                parent_invs.append(parent_invs_cache[parent_id])
278
            except KeyError:
279
                parent_inv = repo.get_inventory(parent_id)
280
                parent_invs.append(parent_inv)
281
                parent_invs_cache[parent_id] = parent_inv
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
282
        if parent_invs == []:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
283
            base_inv = Inventory(root_id=None)
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
284
        else:
285
            base_inv = parent_invs[0]
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
286
        inv_delta = import_git_tree(repo.texts, mapping, "", root_tree, 
287
            base_inv, None, revid, parent_invs, 
288
            target_git_object_retriever._idmap, lookup_object)
289
        try:
290
            basis_id = rev.parent_ids[0]
291
        except IndexError:
292
            basis_id = NULL_REVISION
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
293
        rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
294
                  inv_delta, rev.revision_id, rev.parent_ids)
0.200.301 by Jelmer Vernooij
Cache inventories created.
295
        parent_invs_cache[rev.revision_id] = inv
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
296
        repo.add_revision(rev.revision_id, rev)
0.200.272 by Jelmer Vernooij
Actually store idmap.
297
    target_git_object_retriever._idmap.commit()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
298
299
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
300
class InterGitNonGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
301
    """InterRepository that copies revisions from a Git into a non-Git 
302
    repository."""
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
303
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
304
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
305
306
    @staticmethod
307
    def _get_repo_format_to_test():
308
        return None
309
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
310
    def copy_content(self, revision_id=None, pb=None):
311
        """See InterRepository.copy_content."""
312
        self.fetch(revision_id, pb, find_ghosts=False)
313
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
314
    def fetch_objects(self, determine_wants, mapping, pb=None):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
315
        def progress(text):
0.217.41 by John Carr
Don't fill screen with muttering
316
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
317
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
318
        create_pb = None
319
        if pb is None:
320
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
321
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
322
        recorded_wants = []
323
324
        def record_determine_wants(heads):
325
            wants = determine_wants(heads)
326
            recorded_wants.extend(wants)
327
            return wants
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
328
        
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
329
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
330
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
331
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
332
                self.target.start_write_group()
333
                try:
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
334
                    objects_iter = self.source.fetch_objects(
335
                                record_determine_wants, 
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
336
                                graph_walker, 
337
                                target_git_object_retriever.__getitem__, 
338
                                progress)
339
                    import_git_objects(self.target, mapping, objects_iter, 
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
340
                            target_git_object_retriever, recorded_wants, pb)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
341
                finally:
342
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
343
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
344
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
345
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
346
            if create_pb:
347
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
348
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
349
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, mapping=None,
350
            fetch_spec=None):
0.200.247 by Jelmer Vernooij
Fix git-import.
351
        self.fetch_refs(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts,
352
                mapping=mapping, fetch_spec=fetch_spec)
353
354
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
355
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
356
        if mapping is None:
357
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
358
        if revision_id is not None:
359
            interesting_heads = [revision_id]
360
        elif fetch_spec is not None:
361
            interesting_heads = fetch_spec.heads
362
        else:
363
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
364
        self._refs = {}
365
        def determine_wants(refs):
366
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
367
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
368
                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.
369
            else:
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
370
                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.
371
            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.
372
        self.fetch_objects(determine_wants, mapping, pb)
373
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
374
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
375
    @staticmethod
376
    def is_compatible(source, target):
377
        """Be compatible with GitRepository."""
378
        # FIXME: Also check target uses VersionedFile
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
379
        return (isinstance(source, GitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
380
                target.supports_rich_root() and
381
                not isinstance(target, GitRepository))
382
383
384
class InterGitRepository(InterRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
385
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
386
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
387
    _matching_repo_format = GitRepositoryFormat()
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
388
389
    @staticmethod
390
    def _get_repo_format_to_test():
391
        return None
392
393
    def copy_content(self, revision_id=None, pb=None):
394
        """See InterRepository.copy_content."""
395
        self.fetch(revision_id, pb, find_ghosts=False)
396
397
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
398
              mapping=None, fetch_spec=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
399
        if mapping is None:
400
            mapping = self.source.get_mapping()
401
        def progress(text):
0.200.261 by Jelmer Vernooij
More formatting fixes.
402
            trace.info("git: %s", text)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
403
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
404
        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.
405
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
406
        elif fetch_spec is not None:
407
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.247 by Jelmer Vernooij
Fix git-import.
408
        if fetch_spec is None and revision_id is None:
409
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
410
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
411
            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.
412
413
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
414
        f, commit = r.object_store.add_pack()
415
        try:
416
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
417
            f.close()
418
            commit()
419
        except:
420
            f.close()
421
            raise
422
423
    @staticmethod
424
    def is_compatible(source, target):
425
        """Be compatible with GitRepository."""
426
        return (isinstance(source, GitRepository) and 
427
                isinstance(target, GitRepository))