/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.261 by Jelmer Vernooij
More formatting fixes.
17
from dulwich.objects import (
18
    Commit,
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
19
    Tag,
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
20
    S_ISGITLINK,
0.200.261 by Jelmer Vernooij
More formatting fixes.
21
    )
0.200.355 by Jelmer Vernooij
Allow paranoia checking with -Dverify.
22
from dulwich.object_store import (
23
    tree_lookup_path,
24
    )
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
25
import re
0.200.352 by Jelmer Vernooij
Simplify mode handling.
26
import stat
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
27
28
from bzrlib import (
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
29
    debug,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
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 (
0.239.5 by Jelmer Vernooij
Print user-understandable error message when encountering submodules.
36
    BzrError,
0.200.372 by Jelmer Vernooij
Fix key when looking up old sha's in cache.
37
    NoSuchId,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
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.664 by Jelmer Vernooij
Support submodules during fetch.
44
    TreeReference,
0.200.261 by Jelmer Vernooij
More formatting fixes.
45
    )
46
from bzrlib.repository import (
47
    InterRepository,
48
    )
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
49
from bzrlib.revision import (
50
    NULL_REVISION,
51
    )
0.200.292 by Jelmer Vernooij
Fix formatting.
52
from bzrlib.tsort import (
53
    topo_sort,
54
    )
0.200.417 by Jelmer Vernooij
use insert_record_stream rather than add_lines.
55
from bzrlib.versionedfile import (
56
    FulltextContentFactory,
57
    )
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
58
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
59
from bzrlib.plugins.git.mapping import (
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
60
    DEFAULT_FILE_MODE,
0.200.355 by Jelmer Vernooij
Allow paranoia checking with -Dverify.
61
    inventory_to_tree_and_blobs,
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
62
    mode_is_executable,
0.200.545 by Jelmer Vernooij
Squash revision data only if necessary.
63
    squash_revision,
0.200.490 by Jelmer Vernooij
Warn about unusual modes and escaped XML-invalid characters.
64
    warn_unusual_mode,
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
65
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
66
from bzrlib.plugins.git.object_store import (
67
    BazaarObjectStore,
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
68
    LRUInventoryCache,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
69
    )
0.200.426 by Jelmer Vernooij
Fix import of RemoteGitRepository.
70
from bzrlib.plugins.git.remote import (
71
    RemoteGitRepository,
72
    )
0.200.169 by Jelmer Vernooij
Fix branch cloning.
73
from bzrlib.plugins.git.repository import (
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
74
    GitRepository,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
75
    GitRepositoryFormat,
0.200.426 by Jelmer Vernooij
Fix import of RemoteGitRepository.
76
    LocalGitRepository,
0.200.261 by Jelmer Vernooij
More formatting fixes.
77
    )
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
78
79
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
80
def import_git_blob(texts, mapping, path, hexsha, base_inv, base_inv_shamap,
81
    base_ie, parent_id, revision_id, parent_invs, lookup_object,
82
    executable, symlink):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
83
    """Import a git blob object into a bzr repository.
84
0.200.261 by Jelmer Vernooij
More formatting fixes.
85
    :param texts: VersionedFiles to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
86
    :param path: Path in the tree
87
    :param blob: A git blob
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
88
    :return: Inventory delta for this file
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
89
    """
90
    file_id = mapping.generate_file_id(path)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
91
    if symlink:
92
        cls = InventoryLink
93
    else:
94
        cls = InventoryFile
95
    # We just have to hope this is indeed utf-8:
0.200.354 by Jelmer Vernooij
Support symlinks in conversion to git.
96
    ie = cls(file_id, urlutils.basename(path).decode("utf-8"), parent_id)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
97
    ie.executable = executable
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
98
    # See if this has changed at all
0.200.571 by Jelmer Vernooij
Keep inventory entry children around once we've fetched them.
99
    if base_ie is None:
0.200.372 by Jelmer Vernooij
Fix key when looking up old sha's in cache.
100
        base_sha = None
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
101
    else:
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
102
        try:
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
103
            base_sha = base_inv_shamap.lookup_blob(file_id,
104
                revision_hint=base_ie.revision)
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
105
        except KeyError:
106
            base_sha = None
107
        else:
108
            if (base_sha == hexsha and base_ie.executable == ie.executable
109
                and base_ie.kind == ie.kind):
110
                # If nothing has changed since the base revision, we're done
111
                return [], []
0.200.484 by Jelmer Vernooij
Cope with kind changes.
112
    if base_sha == hexsha and base_ie.kind == ie.kind:
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
113
        ie.text_size = base_ie.text_size
114
        ie.text_sha1 = base_ie.text_sha1
115
        ie.symlink_target = base_ie.symlink_target
0.200.537 by Jelmer Vernooij
Fix handling of not-executable files becoming executable without any other changes.
116
        if ie.executable == base_ie.executable:
117
            ie.revision = base_ie.revision
118
        else:
119
            blob = lookup_object(hexsha)
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
120
    else:
121
        blob = lookup_object(hexsha)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
122
        if ie.kind == "symlink":
0.200.551 by Jelmer Vernooij
Properly set InventoryEntry revision when changing symlink targets.
123
            ie.revision = None
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
124
            ie.symlink_target = blob.data
125
            ie.text_size = None
126
            ie.text_sha1 = None
127
        else:
128
            ie.text_size = len(blob.data)
129
            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).
130
    # Check what revision we should store
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
131
    parent_keys = []
132
    for pinv in parent_invs:
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
133
        if pinv.revision_id == base_inv.revision_id:
0.200.374 by Jelmer Vernooij
Also avoid lookups in the inventory in the tree fetch functions.
134
            pie = base_ie
135
            if pie is None:
136
                continue
137
        else:
138
            try:
139
                pie = pinv[file_id]
140
            except NoSuchId:
141
                continue
0.200.551 by Jelmer Vernooij
Properly set InventoryEntry revision when changing symlink targets.
142
        if pie.text_sha1 == ie.text_sha1 and pie.executable == ie.executable and pie.symlink_target == ie.symlink_target:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
143
            # found a revision in one of the parents to use
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
144
            ie.revision = pie.revision
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
145
            break
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
146
        parent_keys.append((file_id, pie.revision))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
147
    if ie.revision is None:
148
        # Need to store a new revision
149
        ie.revision = revision_id
150
        assert file_id is not None
151
        assert ie.revision is not None
0.200.698 by Jelmer Vernooij
Merge fixes for SHA1s of symlinks.
152
        if ie.kind == 'symlink':
153
            data = ''
154
        else: 
155
            data = blob.data
0.244.1 by INADA Naoki
Fix sha1s for symlinks.
156
        texts.insert_record_stream([FulltextContentFactory((file_id, ie.revision), tuple(parent_keys), ie.text_sha1, data)])
0.200.771 by Jelmer Vernooij
Always set shamap.
157
    shamap = { ie.file_id: hexsha }
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
158
    invdelta = []
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
159
    if base_ie is not None:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
160
        old_path = base_inv.id2path(file_id)
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
161
        if base_ie.kind == "directory":
162
            invdelta.extend(remove_disappeared_children(old_path, base_ie.children, []))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
163
    else:
164
        old_path = None
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
165
    invdelta.append((old_path, path, file_id, ie))
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
166
    return (invdelta, shamap)
0.200.261 by Jelmer Vernooij
More formatting fixes.
167
168
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
169
class SubmodulesRequireSubtrees(BzrError):
0.200.666 by Jelmer Vernooij
Refuse to add tree references to non-subtree formats.
170
    _fmt = """The repository you are fetching from contains submodules. To continue, upgrade your Bazaar repository to a format that supports nested trees, such as 'development-subtree'."""
0.239.5 by Jelmer Vernooij
Print user-understandable error message when encountering submodules.
171
    internal = False
172
173
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
174
def import_git_submodule(texts, mapping, path, hexsha, base_inv, base_ie,
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
175
    parent_id, revision_id, parent_invs, lookup_object):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
176
    file_id = mapping.generate_file_id(path)
177
    ie = TreeReference(file_id, urlutils.basename(path.decode("utf-8")),
178
        parent_id)
179
    ie.revision = revision_id
180
    if base_ie is None:
181
        oldpath = None
182
    else:
183
        oldpath = path
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
184
        if (base_ie.kind == ie.kind and
185
            base_ie.reference_revision == ie.reference_revision):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
186
            ie.revision = base_ie.revision
187
    ie.reference_revision = mapping.revision_id_foreign_to_bzr(hexsha)
188
    texts.insert_record_stream([FulltextContentFactory((file_id, ie.revision), (), None, "")])
189
    invdelta = [(oldpath, path, file_id, ie)]
190
    return invdelta, {}, {}
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
191
192
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
193
def remove_disappeared_children(path, base_children, existing_children):
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
194
    ret = []
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
195
    deletable = [(osutils.pathjoin(path, k), v) for k,v in base_children.iteritems() if k not in existing_children]
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
196
    while deletable:
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
197
        (path, ie) = deletable.pop()
198
        ret.append((path, None, ie.file_id, None))
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
199
        if ie.kind == "directory":
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
200
            for name, child_ie in ie.children.iteritems():
201
                deletable.append((osutils.pathjoin(path, name), child_ie))
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
202
    return ret
203
204
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
205
def import_git_tree(texts, mapping, path, hexsha, base_inv, base_inv_shamap,
206
    base_ie, parent_id, revision_id, parent_invs, lookup_object,
0.200.749 by Jelmer Vernooij
Avoid storing entries for trees in the cache, use blobs instead
207
    allow_submodules=False):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
208
    """Import a git tree object into a bzr repository.
209
0.200.261 by Jelmer Vernooij
More formatting fixes.
210
    :param texts: VersionedFiles object to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
211
    :param path: Path in the tree
212
    :param tree: A git tree object
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
213
    :param base_inv: Base inventory against which to return inventory delta
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
214
    :return: Inventory delta for this subtree
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
215
    """
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
216
    invdelta = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
217
    file_id = mapping.generate_file_id(path)
0.200.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
218
    # We just have to hope this is indeed utf-8:
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
219
    ie = InventoryDirectory(file_id, urlutils.basename(path.decode("utf-8")),
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
220
        parent_id)
0.200.571 by Jelmer Vernooij
Keep inventory entry children around once we've fetched them.
221
    if base_ie is None:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
222
        # Newly appeared here
223
        ie.revision = revision_id
0.200.577 by Jelmer Vernooij
Fix new directory handling.
224
        texts.insert_record_stream([FulltextContentFactory((file_id, ie.revision), (), None, "")])
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
225
        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).
226
    else:
227
        # See if this has changed at all
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
228
        try:
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
229
            base_sha = base_inv_shamap.lookup_tree(file_id)
0.200.752 by Jelmer Vernooij
Actually use shagitmap again to look up trees.
230
        except (KeyError, NotImplementedError):
0.200.287 by Jelmer Vernooij
Skip tree sha's already in the git sha map.
231
            pass
0.200.346 by Jelmer Vernooij
Track unusual file modes.
232
        else:
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
233
            if base_sha == hexsha:
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
234
                # If nothing has changed since the base revision, we're done
0.200.361 by Jelmer Vernooij
Fix existing object lookup issues when pulling from remote branches.
235
                return [], {}, []
0.200.553 by Jelmer Vernooij
Support symlinks being turned into directories.
236
        if base_ie.kind != "directory":
237
            ie.revision = revision_id
0.200.577 by Jelmer Vernooij
Fix new directory handling.
238
            texts.insert_record_stream([FulltextContentFactory((ie.file_id, ie.revision), (), None, "")])
0.200.555 by Jelmer Vernooij
Change kind when turning symlink into dir.
239
            invdelta.append((base_inv.id2path(ie.file_id), path, ie.file_id, ie))
0.200.571 by Jelmer Vernooij
Keep inventory entry children around once we've fetched them.
240
    if base_ie is not None and base_ie.kind == "directory":
241
        base_children = base_ie.children
242
    else:
243
        base_children = {}
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
244
    # Remember for next time
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
245
    existing_children = set()
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
246
    child_modes = {}
0.200.757 by Jelmer Vernooij
Use inventory deltas.
247
    shamap = {}
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
248
    tree = lookup_object(hexsha)
0.200.363 by Jelmer Vernooij
Fix updates of sha map during fetch.
249
    for mode, name, child_hexsha in tree.entries():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
250
        basename = name.decode("utf-8")
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
251
        existing_children.add(basename)
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
252
        child_path = osutils.pathjoin(path, name)
0.200.352 by Jelmer Vernooij
Simplify mode handling.
253
        if stat.S_ISDIR(mode):
0.200.555 by Jelmer Vernooij
Change kind when turning symlink into dir.
254
            subinvdelta, grandchildmodes, subshamap = import_git_tree(
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
255
                    texts, mapping, child_path, child_hexsha, base_inv,
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
256
                    base_inv_shamap, base_children.get(basename), file_id,
257
                    revision_id, parent_invs, lookup_object,
0.200.666 by Jelmer Vernooij
Refuse to add tree references to non-subtree formats.
258
                    allow_submodules=allow_submodules)
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
259
        elif S_ISGITLINK(mode): # submodule
0.200.666 by Jelmer Vernooij
Refuse to add tree references to non-subtree formats.
260
            if not allow_submodules:
261
                raise SubmodulesRequireSubtrees()
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
262
            subinvdelta, grandchildmodes, subshamap = import_git_submodule(
0.200.592 by Jelmer Vernooij
Avoid 'No such revision' error when encountering submodules.
263
                    texts, mapping, child_path, child_hexsha, base_inv, base_children.get(basename),
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
264
                    file_id, revision_id, parent_invs, lookup_object)
0.200.352 by Jelmer Vernooij
Simplify mode handling.
265
        else:
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
266
            subinvdelta, subshamap = import_git_blob(texts, mapping,
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
267
                    child_path, child_hexsha, base_inv, base_inv_shamap,
268
                    base_children.get(basename), file_id,
269
                    revision_id, parent_invs, lookup_object,
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
270
                    mode_is_executable(mode), stat.S_ISLNK(mode))
0.200.757 by Jelmer Vernooij
Use inventory deltas.
271
            grandchildmodes = {}
272
        child_modes.update(grandchildmodes)
273
        invdelta.extend(subinvdelta)
274
        shamap.update(subshamap)
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
275
        if mode not in (stat.S_IFDIR, DEFAULT_FILE_MODE,
276
                        stat.S_IFLNK, DEFAULT_FILE_MODE|0111):
0.200.352 by Jelmer Vernooij
Simplify mode handling.
277
            child_modes[child_path] = mode
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
278
    # Remove any children that have disappeared
0.200.570 by Jelmer Vernooij
Simplify remove disappeared children function.
279
    if base_ie is not None and base_ie.kind == "directory":
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
280
        invdelta.extend(remove_disappeared_children(base_inv.id2path(file_id),
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
281
            base_children, existing_children))
0.200.757 by Jelmer Vernooij
Use inventory deltas.
282
    shamap[file_id] = hexsha
0.200.361 by Jelmer Vernooij
Fix existing object lookup issues when pulling from remote branches.
283
    return invdelta, child_modes, shamap
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
284
285
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
286
def import_git_commit(repo, mapping, head, lookup_object,
0.200.752 by Jelmer Vernooij
Actually use shagitmap again to look up trees.
287
                      target_git_object_retriever, parent_invs_cache):
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
288
    o = lookup_object(head)
289
    rev = mapping.import_commit(o)
290
    # We have to do this here, since we have to walk the tree and
291
    # we need to make sure to import the blobs / trees with the right
292
    # path; this may involve adding them more than once.
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
293
    parent_invs = parent_invs_cache.get_inventories(rev.parent_ids)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
294
    if parent_invs == []:
295
        base_inv = Inventory(root_id=None)
296
        base_ie = None
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
297
        base_inv_shamap = None # Should never be accessed
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
298
    else:
299
        base_inv = parent_invs[0]
300
        base_ie = base_inv.root
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
301
        base_inv_shamap = target_git_object_retriever._idmap.get_inventory_sha_map(base_inv.revision_id)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
302
    inv_delta, unusual_modes, shamap = import_git_tree(repo.texts,
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
303
            mapping, "", o.tree, base_inv, base_inv_shamap, base_ie, None,
304
            rev.revision_id, parent_invs, lookup_object,
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
305
            allow_submodules=getattr(repo._format, "supports_tree_reference", False))
0.200.759 by Jelmer Vernooij
Prepare for using add_entries everywhere.
306
    entries = []
307
    for (oldpath, newpath, fileid, new_ie) in inv_delta:
308
        if newpath is None:
309
            entries.append((fileid, None, None, None))
310
        else:
311
            if new_ie.kind in ("file", "symlink"):
312
                entries.append((fileid, "blob", shamap[fileid], new_ie.revision))
313
            elif new_ie.kind == "directory":
314
                entries.append((fileid, "tree", shamap[fileid], rev.revision_id))
315
            else:
316
                raise AssertionError
0.200.755 by Jelmer Vernooij
Add parent revids argument to add_entries.
317
    target_git_object_retriever._idmap.add_entries(rev.revision_id,
0.200.759 by Jelmer Vernooij
Prepare for using add_entries everywhere.
318
        rev.parent_ids, head, o.tree, entries)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
319
    if unusual_modes != {}:
320
        for path, mode in unusual_modes.iteritems():
321
            warn_unusual_mode(rev.foreign_revid, path, mode)
322
        mapping.import_unusual_file_modes(rev, unusual_modes)
323
    try:
324
        basis_id = rev.parent_ids[0]
325
    except IndexError:
326
        basis_id = NULL_REVISION
327
        base_inv = None
328
    rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
329
              inv_delta, rev.revision_id, rev.parent_ids,
330
              base_inv)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
331
    parent_invs_cache.add(rev.revision_id, inv)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
332
    repo.add_revision(rev.revision_id, rev)
333
    if "verify" in debug.debug_flags:
334
        new_unusual_modes = mapping.export_unusual_file_modes(rev)
335
        if new_unusual_modes != unusual_modes:
336
            raise AssertionError("unusual modes don't match: %r != %r" % (unusual_modes, new_unusual_modes))
337
        objs = inventory_to_tree_and_blobs(inv, repo.texts, mapping, unusual_modes)
0.200.739 by Jelmer Vernooij
Fix -Dverify
338
        for newsha1, newobj, path in objs:
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
339
            assert path is not None
0.200.739 by Jelmer Vernooij
Fix -Dverify
340
            if path == "":
341
                oldsha1 = o.tree
342
            else:
343
                (oldmode, oldsha1) = tree_lookup_path(lookup_object, o.tree, path)
344
            if oldsha1 != newsha1:
345
                raise AssertionError("%r != %r in %s" % (oldsha1, newsha1, path))
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
346
347
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
348
def import_git_objects(repo, mapping, object_iter,
349
    target_git_object_retriever, heads, pb=None, limit=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
350
    """Import a set of git objects into a bzr repository.
351
0.200.483 by Jelmer Vernooij
Add NEWS entry about sha map.
352
    :param repo: Target Bazaar repository
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
353
    :param mapping: Mapping to use
354
    :param object_iter: Iterator over Git objects.
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
355
    :return: Tuple with pack hints and last imported revision id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
356
    """
0.200.469 by Jelmer Vernooij
Fix fetch when revisions are already present locally, just only mapped.
357
    def lookup_object(sha):
358
        try:
359
            return object_iter[sha]
360
        except KeyError:
361
            return target_git_object_retriever[sha]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
362
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
363
    graph = []
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
364
    checked = set()
0.200.734 by Jelmer Vernooij
Don't import head revision twice when pulling from Git.
365
    heads = list(set(heads))
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
366
    parent_invs_cache = LRUInventoryCache(repo)
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
367
    target_git_object_retriever.start_write_group() # FIXME: try/finally
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
368
    # Find and convert commit objects
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
369
    while heads:
370
        if pb is not None:
371
            pb.update("finding revisions to fetch", len(graph), None)
372
        head = heads.pop()
373
        assert isinstance(head, str)
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
374
        try:
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
375
            o = lookup_object(head)
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
376
        except KeyError:
377
            continue
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
378
        if isinstance(o, Commit):
379
            rev = mapping.import_commit(o)
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
380
            if repo.has_revision(rev.revision_id):
381
                continue
0.200.545 by Jelmer Vernooij
Squash revision data only if necessary.
382
            squash_revision(repo, rev)
0.200.668 by Jelmer Vernooij
Fix some places where we were way too much memory for repositories with a large number of entries in the inventory and a large number of revisions.
383
            graph.append((o.id, o.parents))
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
384
            heads.extend([p for p in o.parents if p not in checked])
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
385
        elif isinstance(o, Tag):
0.200.734 by Jelmer Vernooij
Don't import head revision twice when pulling from Git.
386
            if o.object[1] not in checked:
387
                heads.append(o.object[1])
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
388
        else:
389
            trace.warning("Unable to import head object %r" % o)
0.200.668 by Jelmer Vernooij
Fix some places where we were way too much memory for repositories with a large number of entries in the inventory and a large number of revisions.
390
        checked.add(o.id)
391
    del checked
0.200.158 by Jelmer Vernooij
fetch works \o/
392
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
393
    # Create the inventory objects
0.200.680 by Jelmer Vernooij
fetch revisions in batches
394
    batch_size = 100
395
    revision_ids = topo_sort(graph)
396
    pack_hints = []
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
397
    if limit is not None:
398
        revision_ids = revision_ids[:limit]
0.247.3 by Michael Hudson
oh, so it wasn't (particularly) wrong, but it was a bit obscure
399
    last_imported = None
0.200.680 by Jelmer Vernooij
fetch revisions in batches
400
    for offset in range(0, len(revision_ids), batch_size):
401
        repo.start_write_group()
402
        try:
403
            for i, head in enumerate(revision_ids[offset:offset+batch_size]):
404
                if pb is not None:
405
                    pb.update("fetching revisions", offset+i, len(revision_ids))
406
                import_git_commit(repo, mapping, head, lookup_object,
407
                                  target_git_object_retriever,
0.200.752 by Jelmer Vernooij
Actually use shagitmap again to look up trees.
408
                                  parent_invs_cache)
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
409
                last_imported = head
0.200.680 by Jelmer Vernooij
fetch revisions in batches
410
        except:
411
            repo.abort_write_group()
412
            raise
413
        else:
0.200.681 by Jelmer Vernooij
Cope with None.
414
            hint = repo.commit_write_group()
415
            if hint is not None:
416
                pack_hints.extend(hint)
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
417
    target_git_object_retriever.commit_write_group()
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
418
    return pack_hints, last_imported
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
419
420
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
421
class InterGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
422
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
423
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
424
425
    @staticmethod
426
    def _get_repo_format_to_test():
427
        return None
428
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
429
    def copy_content(self, revision_id=None, pb=None):
430
        """See InterRepository.copy_content."""
431
        self.fetch(revision_id, pb, find_ghosts=False)
432
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
433
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
434
        mapping=None, fetch_spec=None):
435
        self.fetch_refs(revision_id=revision_id, pb=pb,
436
            find_ghosts=find_ghosts, mapping=mapping, fetch_spec=fetch_spec)
0.200.247 by Jelmer Vernooij
Fix git-import.
437
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
438
439
class InterGitNonGitRepository(InterGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
440
    """Base InterRepository that copies revisions from a Git into a non-Git
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
441
    repository."""
442
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
443
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False,
0.200.247 by Jelmer Vernooij
Fix git-import.
444
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
445
        if mapping is None:
446
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
447
        if revision_id is not None:
448
            interesting_heads = [revision_id]
449
        elif fetch_spec is not None:
450
            interesting_heads = fetch_spec.heads
451
        else:
452
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
453
        self._refs = {}
454
        def determine_wants(refs):
455
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
456
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
457
                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.
458
            else:
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
459
                ret = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in interesting_heads if revid not in (None, NULL_REVISION)]
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
460
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
461
        (pack_hint, _) = self.fetch_objects(determine_wants, mapping, pb)
0.200.579 by Jelmer Vernooij
Only pack if it makes the target repo smaller.
462
        if pack_hint is not None and self.target._format.pack_compresses:
0.200.578 by Jelmer Vernooij
Only do optimal packing on bzr >= 1.17.
463
            self.target.pack(hint=pack_hint)
0.200.590 by Jelmer Vernooij
Add check to make sure that the requested heads were actually fetched.
464
        if interesting_heads is not None:
465
            present_interesting_heads = self.target.has_revisions(interesting_heads)
466
            missing_interesting_heads = set(interesting_heads) - present_interesting_heads
467
            if missing_interesting_heads:
468
                raise AssertionError("Missing interesting heads: %r" % missing_interesting_heads)
0.200.247 by Jelmer Vernooij
Fix git-import.
469
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
470
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
471
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
472
_GIT_PROGRESS_RE = re.compile(r"(.*?): +(\d+)% \((\d+)/(\d+)\)")
473
def report_git_progress(pb, text):
474
    text = text.rstrip("\r\n")
475
    g = _GIT_PROGRESS_RE.match(text)
476
    if g is not None:
477
        (text, pct, current, total) = g.groups()
478
        pb.update(text, int(current), int(total))
479
    else:
480
        pb.update(text, 0, 0)
481
482
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
483
class InterRemoteGitNonGitRepository(InterGitNonGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
484
    """InterRepository that copies revisions from a remote Git into a non-Git
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
485
    repository."""
486
0.200.582 by Jelmer Vernooij
Use more efficient algorithm for finding out heads.
487
    def get_target_heads(self):
488
        # FIXME: This should be more efficient
489
        all_revs = self.target.all_revision_ids()
490
        parent_map = self.target.get_parent_map(all_revs)
491
        all_parents = set()
492
        map(all_parents.update, parent_map.itervalues())
493
        return set(all_revs) - all_parents
494
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
495
    def fetch_objects(self, determine_wants, mapping, pb=None, limit=None):
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
496
        def progress(text):
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
497
            report_git_progress(pb, text)
0.200.466 by Jelmer Vernooij
Fix finding of heads for fetch_objects.
498
        store = BazaarObjectStore(self.target, mapping)
0.200.484 by Jelmer Vernooij
Cope with kind changes.
499
        self.target.lock_write()
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
500
        try:
0.200.582 by Jelmer Vernooij
Use more efficient algorithm for finding out heads.
501
            heads = self.get_target_heads()
0.200.484 by Jelmer Vernooij
Cope with kind changes.
502
            graph_walker = store.get_graph_walker(
503
                    [store._lookup_revision_sha1(head) for head in heads])
504
            recorded_wants = []
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
505
0.200.484 by Jelmer Vernooij
Cope with kind changes.
506
            def record_determine_wants(heads):
507
                wants = determine_wants(heads)
508
                recorded_wants.extend(wants)
509
                return wants
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
510
0.200.484 by Jelmer Vernooij
Cope with kind changes.
511
            create_pb = None
512
            if pb is None:
513
                create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
514
            try:
0.200.680 by Jelmer Vernooij
fetch revisions in batches
515
                objects_iter = self.source.fetch_objects(
516
                            record_determine_wants, graph_walker,
517
                            store.get_raw, progress)
518
                return import_git_objects(self.target, mapping,
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
519
                    objects_iter, store, recorded_wants, pb, limit)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
520
            finally:
0.200.484 by Jelmer Vernooij
Cope with kind changes.
521
                if create_pb:
522
                    create_pb.finished()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
523
        finally:
0.200.484 by Jelmer Vernooij
Cope with kind changes.
524
            self.target.unlock()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
525
526
    @staticmethod
527
    def is_compatible(source, target):
528
        """Be compatible with GitRepository."""
529
        # FIXME: Also check target uses VersionedFile
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
530
        return (isinstance(source, RemoteGitRepository) and
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
531
                target.supports_rich_root() and
532
                not isinstance(target, GitRepository))
533
534
535
class InterLocalGitNonGitRepository(InterGitNonGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
536
    """InterRepository that copies revisions from a local Git into a non-Git
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
537
    repository."""
538
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
539
    def fetch_objects(self, determine_wants, mapping, pb=None, limit=None):
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
540
        """Fetch objects.
541
        """
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
542
        wants = determine_wants(self.source._git.get_refs())
543
        create_pb = None
544
        if pb is None:
545
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
546
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
547
        try:
548
            self.target.lock_write()
549
            try:
0.200.680 by Jelmer Vernooij
fetch revisions in batches
550
                return import_git_objects(self.target, mapping,
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
551
                    self.source._git.object_store,
552
                    target_git_object_retriever, wants, pb, limit)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
553
            finally:
554
                self.target.unlock()
555
        finally:
556
            if create_pb:
557
                create_pb.finished()
558
559
    @staticmethod
560
    def is_compatible(source, target):
561
        """Be compatible with GitRepository."""
562
        # FIXME: Also check target uses VersionedFile
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
563
        return (isinstance(source, LocalGitRepository) and
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
564
                target.supports_rich_root() and
565
                not isinstance(target, GitRepository))
566
567
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
568
class InterGitGitRepository(InterGitRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
569
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
570
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
571
    def fetch_objects(self, determine_wants, mapping, pb=None):
572
        def progress(text):
573
            trace.note("git: %s", text)
574
        graphwalker = self.target._git.get_graph_walker()
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
575
        if (isinstance(self.source, LocalGitRepository) and
576
            isinstance(self.target, LocalGitRepository)):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
577
            return self.source._git.fetch(self.target._git, determine_wants,
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
578
                progress)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
579
        elif (isinstance(self.source, LocalGitRepository) and
580
              isinstance(self.target, RemoteGitRepository)):
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
581
            raise NotImplementedError
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
582
        elif (isinstance(self.source, RemoteGitRepository) and
583
              isinstance(self.target, LocalGitRepository)):
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
584
            f, commit = self.target._git.object_store.add_thin_pack()
585
            try:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
586
                refs = self.source._git.fetch_pack(determine_wants,
587
                    graphwalker, f.write, progress)
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
588
                commit()
589
                return refs
590
            except:
591
                f.close()
592
                raise
593
        else:
594
            raise AssertionError
595
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
596
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
597
              mapping=None, fetch_spec=None, branches=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
598
        if mapping is None:
599
            mapping = self.source.get_mapping()
600
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
601
        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.
602
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
603
        elif fetch_spec is not None:
604
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
605
        if branches is not None:
606
            determine_wants = lambda x: [x[y] for y in branches if not x[y] in r.object_store]
607
        elif fetch_spec is None and revision_id is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
608
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
609
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
610
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
611
        return self.fetch_objects(determine_wants, mapping)[0]
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
612
613
614
    @staticmethod
615
    def is_compatible(source, target):
616
        """Be compatible with GitRepository."""
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
617
        return (isinstance(source, GitRepository) and
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
618
                isinstance(target, GitRepository))