/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.910 by Jelmer Vernooij
update copyright years
1
# Copyright (C) 2008-2010 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.814 by Jelmer Vernooij
Avoid the use of InventoryDirectory.children. This speeds up
20
    Tree,
0.200.1407 by Jelmer Vernooij
Don't consider submodule modes unusual.
21
    S_IFGITLINK,
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
22
    S_ISGITLINK,
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
23
    ZERO_SHA,
0.200.261 by Jelmer Vernooij
More formatting fixes.
24
    )
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
25
from dulwich.object_store import (
26
    tree_lookup_path,
27
    )
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
28
from dulwich.walk import Walker
0.200.830 by Jelmer Vernooij
Bump minimum dulwich version.
29
from itertools import (
30
    imap,
31
    )
0.200.819 by Jelmer Vernooij
Avoid decoding basename twice.
32
import posixpath
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
33
import re
0.200.352 by Jelmer Vernooij
Simplify mode handling.
34
import stat
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
35
36
from bzrlib import (
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
37
    debug,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
38
    osutils,
0.200.261 by Jelmer Vernooij
More formatting fixes.
39
    trace,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
40
    ui,
41
    )
42
from bzrlib.errors import (
0.239.5 by Jelmer Vernooij
Print user-understandable error message when encountering submodules.
43
    BzrError,
0.200.372 by Jelmer Vernooij
Fix key when looking up old sha's in cache.
44
    NoSuchId,
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
45
    )
0.200.261 by Jelmer Vernooij
More formatting fixes.
46
from bzrlib.inventory import (
47
    Inventory,
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
48
    InventoryDirectory,
49
    InventoryFile,
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
50
    InventoryLink,
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
51
    TreeReference,
0.200.261 by Jelmer Vernooij
More formatting fixes.
52
    )
53
from bzrlib.repository import (
54
    InterRepository,
55
    )
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
56
from bzrlib.revision import (
57
    NULL_REVISION,
58
    )
0.200.1187 by Jelmer Vernooij
Use InventoryRevisionTree.
59
try:
60
    from bzrlib.revisiontree import InventoryRevisionTree
61
except ImportError: # bzr < 2.4
62
    from bzrlib.revisiontree import RevisionTree as InventoryRevisionTree
0.200.1023 by Jelmer Vernooij
Set and verify testament.
63
from bzrlib.testament import (
64
    StrictTestament3,
65
    )
0.200.292 by Jelmer Vernooij
Fix formatting.
66
from bzrlib.tsort import (
67
    topo_sort,
68
    )
0.200.417 by Jelmer Vernooij
use insert_record_stream rather than add_lines.
69
from bzrlib.versionedfile import (
0.200.811 by Jelmer Vernooij
Use ChunkedContentFactory when possible.
70
    ChunkedContentFactory,
0.200.417 by Jelmer Vernooij
use insert_record_stream rather than add_lines.
71
    )
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
72
0.200.1403 by Jelmer Vernooij
Cope with tags pointing at tree objects when cloning local git repositories.
73
from bzrlib.plugins.git.errors import (
74
    NotCommitError,
75
    )
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
76
from bzrlib.plugins.git.mapping import (
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
77
    DEFAULT_FILE_MODE,
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
78
    mode_is_executable,
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
79
    mode_kind,
0.200.490 by Jelmer Vernooij
Warn about unusual modes and escaped XML-invalid characters.
80
    warn_unusual_mode,
0.231.2 by Jelmer Vernooij
Add -Dverify flag (not fully implemented yet).
81
    )
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
82
from bzrlib.plugins.git.object_store import (
83
    BazaarObjectStore,
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
84
    LRUTreeCache,
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
85
    _tree_to_objects,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
86
    )
0.259.4 by Jelmer Vernooij
Put determine_wants methods on InterRepo.
87
from bzrlib.plugins.git.refs import extract_tags
0.200.426 by Jelmer Vernooij
Fix import of RemoteGitRepository.
88
from bzrlib.plugins.git.remote import (
89
    RemoteGitRepository,
90
    )
0.200.169 by Jelmer Vernooij
Fix branch cloning.
91
from bzrlib.plugins.git.repository import (
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
92
    GitRepository,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
93
    GitRepositoryFormat,
0.200.426 by Jelmer Vernooij
Fix import of RemoteGitRepository.
94
    LocalGitRepository,
0.200.261 by Jelmer Vernooij
More formatting fixes.
95
    )
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
96
97
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
98
def import_git_blob(texts, mapping, path, name, (base_hexsha, hexsha), 
0.200.848 by Jelmer Vernooij
remove unnecessary parent_inv_shamap.
99
        base_inv, parent_id, revision_id,
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
100
        parent_invs, lookup_object, (base_mode, mode), store_updater,
101
        lookup_file_id):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
102
    """Import a git blob object into a bzr repository.
103
0.200.261 by Jelmer Vernooij
More formatting fixes.
104
    :param texts: VersionedFiles to add to
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
105
    :param path: Path in the tree
106
    :param blob: A git blob
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
107
    :return: Inventory delta for this file
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
108
    """
0.252.28 by Jelmer Vernooij
Don't import control files.
109
    if mapping.is_control_file(path):
110
        return []
0.200.816 by Jelmer Vernooij
Leave mode handling for blobs to import_git_blob.
111
    if base_hexsha == hexsha and base_mode == mode:
112
        # If nothing has changed since the base revision, we're done
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
113
        return []
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
114
    file_id = lookup_file_id(path)
0.200.816 by Jelmer Vernooij
Leave mode handling for blobs to import_git_blob.
115
    if stat.S_ISLNK(mode):
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
116
        cls = InventoryLink
117
    else:
118
        cls = InventoryFile
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
119
    ie = cls(file_id, name.decode("utf-8"), parent_id)
0.200.995 by Jelmer Vernooij
Support newer versions of bzr where only some InventoryFile/InventoryLink attributes are writable.
120
    if ie.kind == "file":
121
        ie.executable = mode_is_executable(mode)
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
122
    if base_hexsha == hexsha and mode_kind(base_mode) == mode_kind(mode):
123
        base_ie = base_inv[base_inv.path2id(path)]
0.200.373 by Jelmer Vernooij
Re-use inventory entries rather than looking them up again and again.
124
        ie.text_size = base_ie.text_size
125
        ie.text_sha1 = base_ie.text_sha1
0.200.995 by Jelmer Vernooij
Support newer versions of bzr where only some InventoryFile/InventoryLink attributes are writable.
126
        if ie.kind == "symlink":
127
            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.
128
        if ie.executable == base_ie.executable:
129
            ie.revision = base_ie.revision
130
        else:
131
            blob = lookup_object(hexsha)
0.200.304 by Jelmer Vernooij
Try a bit harder to avoid fetching objects we don't need.
132
    else:
133
        blob = lookup_object(hexsha)
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
134
        if ie.kind == "symlink":
0.200.551 by Jelmer Vernooij
Properly set InventoryEntry revision when changing symlink targets.
135
            ie.revision = None
0.200.1344 by Jelmer Vernooij
Unicode symlinks should be unicode in inventory entries.
136
            ie.symlink_target = blob.data.decode("utf-8")
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
137
        else:
0.200.830 by Jelmer Vernooij
Bump minimum dulwich version.
138
            ie.text_size = sum(imap(len, blob.chunked))
139
            ie.text_sha1 = osutils.sha_strings(blob.chunked)
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
140
    # Check what revision we should store
0.200.283 by Jelmer Vernooij
Avoid storing repeated texts for blobs.
141
    parent_keys = []
0.200.904 by Jelmer Vernooij
Fix inconsistent parents.
142
    for pinv in parent_invs:
0.200.829 by Jelmer Vernooij
Cope with the fact that _type is gone in upstream dulwich.
143
        try:
144
            pie = pinv[file_id]
145
        except NoSuchId:
146
            continue
0.252.25 by Jelmer Vernooij
Reformatting.
147
        if (pie.text_sha1 == ie.text_sha1 and
148
            pie.executable == ie.executable and
149
            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).
150
            # 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.
151
            ie.revision = pie.revision
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
152
            break
0.200.904 by Jelmer Vernooij
Fix inconsistent parents.
153
        parent_key = (file_id, pie.revision)
154
        if not parent_key in parent_keys:
155
            parent_keys.append(parent_key)
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
156
    if ie.revision is None:
157
        # Need to store a new revision
158
        ie.revision = revision_id
159
        assert ie.revision is not None
0.200.698 by Jelmer Vernooij
Merge fixes for SHA1s of symlinks.
160
        if ie.kind == 'symlink':
0.200.811 by Jelmer Vernooij
Use ChunkedContentFactory when possible.
161
            chunks = []
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
162
        else:
0.200.830 by Jelmer Vernooij
Bump minimum dulwich version.
163
            chunks = blob.chunked
0.252.25 by Jelmer Vernooij
Reformatting.
164
        texts.insert_record_stream([
165
            ChunkedContentFactory((file_id, ie.revision),
166
                tuple(parent_keys), ie.text_sha1, chunks)])
0.200.572 by Jelmer Vernooij
Avoid some extra path lookups.
167
    invdelta = []
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
168
    if base_hexsha is not None:
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
169
        old_path = path.decode("utf-8") # Renames are not supported yet
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
170
        if stat.S_ISDIR(base_mode):
0.200.826 by Jelmer Vernooij
Fix some long lines.
171
            invdelta.extend(remove_disappeared_children(base_inv, old_path,
172
                lookup_object(base_hexsha), [], lookup_object))
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
173
    else:
174
        old_path = None
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
175
    new_path = path.decode("utf-8")
176
    invdelta.append((old_path, new_path, file_id, ie))
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
177
    if base_hexsha != hexsha:
0.200.952 by Jelmer Vernooij
Write git pack files rather than loose objects.
178
        store_updater.add_object(blob, ie, path)
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
179
    return invdelta
0.200.261 by Jelmer Vernooij
More formatting fixes.
180
181
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
182
class SubmodulesRequireSubtrees(BzrError):
0.200.1309 by Jelmer Vernooij
Break some more long lines.
183
    _fmt = ("The repository you are fetching from contains submodules. "
184
            "To continue, upgrade your Bazaar repository to a format that "
185
            "supports nested trees, such as 'development-subtree'.")
0.239.5 by Jelmer Vernooij
Print user-understandable error message when encountering submodules.
186
    internal = False
187
188
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
189
def import_git_submodule(texts, mapping, path, name, (base_hexsha, hexsha),
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
190
    base_inv, parent_id, revision_id, parent_invs, lookup_object,
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
191
    (base_mode, mode), store_updater, lookup_file_id):
0.200.1309 by Jelmer Vernooij
Break some more long lines.
192
    """Import a git submodule."""
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
193
    if base_hexsha == hexsha and base_mode == mode:
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
194
        return [], {}
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
195
    file_id = lookup_file_id(path)
0.200.1408 by Jelmer Vernooij
Remove old ie children when converting directory into tree reference.
196
    invdelta = []
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
197
    ie = TreeReference(file_id, name.decode("utf-8"), parent_id)
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
198
    ie.revision = revision_id
0.200.1408 by Jelmer Vernooij
Remove old ie children when converting directory into tree reference.
199
    if base_hexsha is not None:
200
        old_path = path.decode("utf-8") # Renames are not supported yet
201
        if stat.S_ISDIR(base_mode):
202
            invdelta.extend(remove_disappeared_children(base_inv, old_path,
203
                lookup_object(base_hexsha), [], lookup_object))
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
204
    else:
0.200.1408 by Jelmer Vernooij
Remove old ie children when converting directory into tree reference.
205
        old_path = None
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
206
    ie.reference_revision = mapping.revision_id_foreign_to_bzr(hexsha)
0.252.25 by Jelmer Vernooij
Reformatting.
207
    texts.insert_record_stream([
208
        ChunkedContentFactory((file_id, ie.revision), (), None, [])])
0.200.1408 by Jelmer Vernooij
Remove old ie children when converting directory into tree reference.
209
    invdelta.append((old_path, path, file_id, ie))
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
210
    return invdelta, {}
0.200.540 by Jelmer Vernooij
Handle submodules explicitly.
211
212
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
213
def remove_disappeared_children(base_inv, path, base_tree, existing_children,
214
        lookup_object):
0.200.930 by Jelmer Vernooij
Add assert demonstrating 571055 and triggering it for all target formats.
215
    """Generate an inventory delta for removed children.
216
217
    :param base_inv: Base inventory against which to generate the 
218
        inventory delta.
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
219
    :param path: Path to process (unicode)
0.200.930 by Jelmer Vernooij
Add assert demonstrating 571055 and triggering it for all target formats.
220
    :param base_tree: Git Tree base object
221
    :param existing_children: Children that still exist
222
    :param lookup_object: Lookup a git object by its SHA1
223
    :return: Inventory delta, as list
224
    """
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
225
    assert type(path) is unicode
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
226
    ret = []
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
227
    for name, mode, hexsha in base_tree.iteritems():
228
        if name in existing_children:
229
            continue
230
        c_path = posixpath.join(path, name.decode("utf-8"))
0.200.930 by Jelmer Vernooij
Add assert demonstrating 571055 and triggering it for all target formats.
231
        file_id = base_inv.path2id(c_path)
232
        assert file_id is not None
233
        ret.append((c_path, None, file_id, None))
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
234
        if stat.S_ISDIR(mode):
235
            ret.extend(remove_disappeared_children(
236
                base_inv, c_path, lookup_object(hexsha), [], lookup_object))
0.200.552 by Jelmer Vernooij
Cope with directories becoming symlinks.
237
    return ret
238
239
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
240
def import_git_tree(texts, mapping, path, name, (base_hexsha, hexsha),
0.200.848 by Jelmer Vernooij
remove unnecessary parent_inv_shamap.
241
        base_inv, parent_id, revision_id, parent_invs,
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
242
        lookup_object, (base_mode, mode), store_updater,
243
        lookup_file_id, allow_submodules=False):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
244
    """Import a git tree object into a bzr repository.
245
0.200.261 by Jelmer Vernooij
More formatting fixes.
246
    :param texts: VersionedFiles object to add to
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
247
    :param path: Path in the tree (str)
248
    :param name: Name of the tree (str)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
249
    :param tree: A git tree object
0.229.2 by Jelmer Vernooij
Initial work relying on inventory deltas.
250
    :param base_inv: Base inventory against which to return inventory delta
0.229.1 by Jelmer Vernooij
Start working with inventory deltas.
251
    :return: Inventory delta for this subtree
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
252
    """
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
253
    assert type(path) is str
254
    assert type(name) is str
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
255
    if base_hexsha == hexsha and base_mode == mode:
256
        # If nothing has changed since the base revision, we're done
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
257
        return [], {}
0.200.344 by Jelmer Vernooij
Clarify names, use convenience function
258
    invdelta = []
0.200.896 by Jelmer Vernooij
Add separate function for looking up file ids.
259
    file_id = lookup_file_id(path)
0.200.297 by Jelmer Vernooij
Cope with non-ascii characters in filenames (needs a test..).
260
    # We just have to hope this is indeed utf-8:
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
261
    ie = InventoryDirectory(file_id, name.decode("utf-8"), parent_id)
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
262
    tree = lookup_object(hexsha)
263
    if base_hexsha is None:
264
        base_tree = None
0.200.823 by Jelmer Vernooij
Simplify logic in import_git_tree a bit.
265
        old_path = None # Newly appeared here
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
266
    else:
267
        base_tree = lookup_object(base_hexsha)
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
268
        old_path = path.decode("utf-8") # Renames aren't supported yet
269
    new_path = path.decode("utf-8")
0.200.823 by Jelmer Vernooij
Simplify logic in import_git_tree a bit.
270
    if base_tree is None or type(base_tree) is not Tree:
271
        ie.revision = revision_id
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
272
        invdelta.append((old_path, new_path, ie.file_id, ie))
0.252.24 by Jelmer Vernooij
Support reading fileid map.
273
        texts.insert_record_stream([
274
            ChunkedContentFactory((ie.file_id, ie.revision), (), None, [])])
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
275
    # Remember for next time
0.200.300 by Jelmer Vernooij
Fix recursive deletion of dirs.
276
    existing_children = set()
0.200.345 by Jelmer Vernooij
Keep track of file modes to use.
277
    child_modes = {}
0.200.1147 by Jelmer Vernooij
Use Tree.items() rather than Tree.entries().
278
    for name, child_mode, child_hexsha in tree.iteritems():
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
279
        existing_children.add(name)
0.200.819 by Jelmer Vernooij
Avoid decoding basename twice.
280
        child_path = posixpath.join(path, name)
0.200.814 by Jelmer Vernooij
Avoid the use of InventoryDirectory.children. This speeds up
281
        if type(base_tree) is Tree:
282
            try:
283
                child_base_mode, child_base_hexsha = base_tree[name]
284
            except KeyError:
285
                child_base_hexsha = None
286
                child_base_mode = 0
287
        else:
288
            child_base_hexsha = None
289
            child_base_mode = 0
0.200.816 by Jelmer Vernooij
Leave mode handling for blobs to import_git_blob.
290
        if stat.S_ISDIR(child_mode):
0.252.25 by Jelmer Vernooij
Reformatting.
291
            subinvdelta, grandchildmodes = import_git_tree(texts, mapping,
292
                child_path, name, (child_base_hexsha, child_hexsha), base_inv,
0.200.1059 by Jelmer Vernooij
Fix graph tests.
293
                file_id, revision_id, parent_invs, lookup_object,
0.252.25 by Jelmer Vernooij
Reformatting.
294
                (child_base_mode, child_mode), store_updater, lookup_file_id,
295
                allow_submodules=allow_submodules)
0.200.816 by Jelmer Vernooij
Leave mode handling for blobs to import_git_blob.
296
        elif S_ISGITLINK(child_mode): # submodule
0.200.666 by Jelmer Vernooij
Refuse to add tree references to non-subtree formats.
297
            if not allow_submodules:
298
                raise SubmodulesRequireSubtrees()
0.252.25 by Jelmer Vernooij
Reformatting.
299
            subinvdelta, grandchildmodes = import_git_submodule(texts, mapping,
300
                child_path, name, (child_base_hexsha, child_hexsha), base_inv,
301
                file_id, revision_id, parent_invs, lookup_object,
302
                (child_base_mode, child_mode), store_updater, lookup_file_id)
0.200.352 by Jelmer Vernooij
Simplify mode handling.
303
        else:
0.200.1328 by Jelmer Vernooij
More test fixes.
304
            if not mapping.is_special_file(name):
305
                subinvdelta = import_git_blob(texts, mapping, child_path, name,
306
                    (child_base_hexsha, child_hexsha), base_inv, file_id,
307
                    revision_id, parent_invs, lookup_object,
308
                    (child_base_mode, child_mode), store_updater, lookup_file_id)
309
            else:
310
                subinvdelta = []
0.200.757 by Jelmer Vernooij
Use inventory deltas.
311
            grandchildmodes = {}
312
        child_modes.update(grandchildmodes)
313
        invdelta.extend(subinvdelta)
0.200.816 by Jelmer Vernooij
Leave mode handling for blobs to import_git_blob.
314
        if child_mode not in (stat.S_IFDIR, DEFAULT_FILE_MODE,
0.200.1407 by Jelmer Vernooij
Don't consider submodule modes unusual.
315
                        stat.S_IFLNK, DEFAULT_FILE_MODE|0111,
316
                        S_IFGITLINK):
0.200.879 by Jelmer Vernooij
Fix unusual modes.
317
            child_modes[child_path] = child_mode
0.229.3 by Jelmer Vernooij
Use inventory deltas internally so fetch is O(changes) rather than O(tree).
318
    # Remove any children that have disappeared
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
319
    if base_tree is not None and type(base_tree) is Tree:
0.200.984 by Jelmer Vernooij
Handle non-ascii characters in filenames.
320
        invdelta.extend(remove_disappeared_children(base_inv, old_path,
0.200.820 by Jelmer Vernooij
Avoid relying on InventoryDirectory.children.
321
            base_tree, existing_children, lookup_object))
0.200.952 by Jelmer Vernooij
Write git pack files rather than loose objects.
322
    store_updater.add_object(tree, ie, path)
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
323
    return invdelta, child_modes
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
324
325
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
326
def verify_commit_reconstruction(target_git_object_retriever, lookup_object,
0.200.1047 by Jelmer Vernooij
Fix -Dverify.
327
    o, rev, ret_tree, parent_trees, mapping, unusual_modes, verifiers):
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
328
    new_unusual_modes = mapping.export_unusual_file_modes(rev)
329
    if new_unusual_modes != unusual_modes:
330
        raise AssertionError("unusual modes don't match: %r != %r" % (
331
            unusual_modes, new_unusual_modes))
332
    # Verify that we can reconstruct the commit properly
0.200.1047 by Jelmer Vernooij
Fix -Dverify.
333
    rec_o = target_git_object_retriever._reconstruct_commit(rev, o.tree, True,
334
        verifiers)
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
335
    if rec_o != o:
336
        raise AssertionError("Reconstructed commit differs: %r != %r" % (
337
            rec_o, o))
338
    diff = []
339
    new_objs = {}
340
    for path, obj, ie in _tree_to_objects(ret_tree, parent_trees,
0.200.1309 by Jelmer Vernooij
Break some more long lines.
341
        target_git_object_retriever._cache.idmap, unusual_modes,
342
        mapping.BZR_DUMMY_FILE):
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
343
        old_obj_id = tree_lookup_path(lookup_object, o.tree, path)[1]
344
        new_objs[path] = obj
345
        if obj.id != old_obj_id:
346
            diff.append((path, lookup_object(old_obj_id), obj))
347
    for (path, old_obj, new_obj) in diff:
348
        while (old_obj.type_name == "tree" and
349
               new_obj.type_name == "tree" and
350
               sorted(old_obj) == sorted(new_obj)):
351
            for name in old_obj:
352
                if old_obj[name][0] != new_obj[name][0]:
0.252.25 by Jelmer Vernooij
Reformatting.
353
                    raise AssertionError("Modes for %s differ: %o != %o" %
354
                        (path, old_obj[name][0], new_obj[name][0]))
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
355
                if old_obj[name][1] != new_obj[name][1]:
356
                    # Found a differing child, delve deeper
357
                    path = posixpath.join(path, name)
358
                    old_obj = lookup_object(old_obj[name][1])
359
                    new_obj = new_objs[path]
360
                    break
361
        raise AssertionError("objects differ for %s: %r != %r" % (path,
362
            old_obj, new_obj))
363
364
0.200.1409 by Jelmer Vernooij
Support fetching into repositories that are stacked.
365
def ensure_inventories_in_repo(repo, trees):
366
    real_inv_vf = repo.inventories.without_fallbacks()
367
    for t in trees:
368
        revid = t.get_revision_id()
369
        if not real_inv_vf.get_parent_map([(revid, )]):
370
            repo.add_inventory(revid, t.inventory, t.get_parent_ids())
371
372
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
373
def import_git_commit(repo, mapping, head, lookup_object,
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
374
                      target_git_object_retriever, trees_cache):
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
375
    o = lookup_object(head)
0.261.5 by Jelmer Vernooij
Fix looking up of parents during fetch.
376
    # Note that this uses mapping.revision_id_foreign_to_bzr. If the parents
377
    # were bzr roundtripped revisions they would be specified in the
378
    # roundtrip data.
0.261.4 by Jelmer Vernooij
Fix tests.
379
    rev, roundtrip_revid, verifiers = mapping.import_commit(
0.261.5 by Jelmer Vernooij
Fix looking up of parents during fetch.
380
        o, mapping.revision_id_foreign_to_bzr)
0.200.1329 by Jelmer Vernooij
Fix more tests.
381
    if roundtrip_revid is not None:
382
        original_revid = rev.revision_id
383
        rev.revision_id = roundtrip_revid
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
384
    # We have to do this here, since we have to walk the tree and
385
    # we need to make sure to import the blobs / trees with the right
386
    # path; this may involve adding them more than once.
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
387
    parent_trees = trees_cache.revision_trees(rev.parent_ids)
0.200.1409 by Jelmer Vernooij
Support fetching into repositories that are stacked.
388
    ensure_inventories_in_repo(repo, parent_trees)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
389
    if parent_trees == []:
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
390
        base_inv = Inventory(root_id=None)
0.200.814 by Jelmer Vernooij
Avoid the use of InventoryDirectory.children. This speeds up
391
        base_tree = None
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
392
        base_mode = None
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
393
    else:
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
394
        base_inv = parent_trees[0].inventory
0.200.814 by Jelmer Vernooij
Avoid the use of InventoryDirectory.children. This speeds up
395
        base_tree = lookup_object(o.parents[0]).tree
0.200.817 by Jelmer Vernooij
Deal with all modes locally.
396
        base_mode = stat.S_IFDIR
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
397
    store_updater = target_git_object_retriever._get_updater(rev)
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
398
    tree_supplement = mapping.get_fileid_map(lookup_object, o.tree)
0.200.839 by Jelmer Vernooij
Add convenience object for updating the object store caching layer.
399
    inv_delta, unusual_modes = import_git_tree(repo.texts,
0.200.988 by Jelmer Vernooij
Some formatting cleanups.
400
            mapping, "", "", (base_tree, o.tree), base_inv,
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
401
            None, rev.revision_id, [p.inventory for p in parent_trees],
402
            lookup_object, (base_mode, stat.S_IFDIR), store_updater,
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
403
            tree_supplement.lookup_file_id,
0.200.1309 by Jelmer Vernooij
Break some more long lines.
404
            allow_submodules=getattr(repo._format, "supports_tree_reference",
405
                False))
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
406
    if unusual_modes != {}:
407
        for path, mode in unusual_modes.iteritems():
408
            warn_unusual_mode(rev.foreign_revid, path, mode)
409
        mapping.import_unusual_file_modes(rev, unusual_modes)
410
    try:
411
        basis_id = rev.parent_ids[0]
412
    except IndexError:
413
        basis_id = NULL_REVISION
414
        base_inv = None
415
    rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
0.200.988 by Jelmer Vernooij
Some formatting cleanups.
416
              inv_delta, rev.revision_id, rev.parent_ids, base_inv)
0.200.1195 by Jelmer Vernooij
Cope with new StrictTestament3 arguments.
417
    ret_tree = InventoryRevisionTree(repo, inv, rev.revision_id)
0.200.1329 by Jelmer Vernooij
Fix more tests.
418
    # Check verifiers
419
    if verifiers and roundtrip_revid is not None:
420
        if getattr(StrictTestament3, "from_revision_tree", None):
421
            testament = StrictTestament3(rev, ret_tree)
422
        else: # bzr < 2.4
423
            testament = StrictTestament3(rev, inv)
424
        calculated_verifiers = { "testament3-sha1": testament.as_sha1() }
425
        if calculated_verifiers != verifiers:
426
            trace.mutter("Testament SHA1 %r for %r did not match %r.",
427
                         calculated_verifiers["testament3-sha1"],
428
                         rev.revision_id, verifiers["testament3-sha1"])
429
            rev.revision_id = original_revid
430
            rev.inventory_sha1, inv = repo.add_inventory_by_delta(basis_id,
431
              inv_delta, rev.revision_id, rev.parent_ids, base_inv)
432
            ret_tree = InventoryRevisionTree(repo, inv, rev.revision_id)
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
433
    else:
434
        calculated_verifiers = {}
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
435
    store_updater.add_object(o, calculated_verifiers, None)
436
    store_updater.finish()
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
437
    trees_cache.add(ret_tree)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
438
    repo.add_revision(rev.revision_id, rev)
439
    if "verify" in debug.debug_flags:
0.200.883 by Jelmer Vernooij
Add function for verifying reconstruction of objects still works.
440
        verify_commit_reconstruction(target_git_object_retriever, 
441
            lookup_object, o, rev, ret_tree, parent_trees, mapping,
0.200.1047 by Jelmer Vernooij
Fix -Dverify.
442
            unusual_modes, verifiers)
0.200.679 by Jelmer Vernooij
Moving commit import functionality to a separate function.
443
444
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
445
def import_git_objects(repo, mapping, object_iter,
446
    target_git_object_retriever, heads, pb=None, limit=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
447
    """Import a set of git objects into a bzr repository.
448
0.200.483 by Jelmer Vernooij
Add NEWS entry about sha map.
449
    :param repo: Target Bazaar repository
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
450
    :param mapping: Mapping to use
451
    :param object_iter: Iterator over Git objects.
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
452
    :return: Tuple with pack hints and last imported revision id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
453
    """
0.200.469 by Jelmer Vernooij
Fix fetch when revisions are already present locally, just only mapped.
454
    def lookup_object(sha):
455
        try:
456
            return object_iter[sha]
457
        except KeyError:
458
            return target_git_object_retriever[sha]
0.200.158 by Jelmer Vernooij
fetch works \o/
459
    graph = []
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
460
    checked = set()
0.200.734 by Jelmer Vernooij
Don't import head revision twice when pulling from Git.
461
    heads = list(set(heads))
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
462
    trees_cache = LRUTreeCache(repo)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
463
    # Find and convert commit objects
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
464
    while heads:
465
        if pb is not None:
466
            pb.update("finding revisions to fetch", len(graph), None)
467
        head = heads.pop()
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
468
        if head == ZERO_SHA:
469
            continue
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
470
        assert isinstance(head, str)
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
471
        try:
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
472
            o = lookup_object(head)
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
473
        except KeyError:
474
            continue
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
475
        if isinstance(o, Commit):
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
476
            rev, roundtrip_revid, verifiers = mapping.import_commit(o,
0.261.6 by Jelmer Vernooij
Use mapping.revision_id_foreign_to_bzr to find parents everywhere.
477
                mapping.revision_id_foreign_to_bzr)
0.200.1021 by Jelmer Vernooij
Put testament sha1 in revisions.
478
            if (repo.has_revision(rev.revision_id) or
479
                (roundtrip_revid and repo.has_revision(roundtrip_revid))):
0.200.295 by Jelmer Vernooij
Don't re-import revisions already fetched.
480
                continue
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.
481
            graph.append((o.id, o.parents))
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
482
            heads.extend([p for p in o.parents if p not in checked])
0.200.303 by Jelmer Vernooij
Cope with tags during fetch.
483
        elif isinstance(o, Tag):
0.200.734 by Jelmer Vernooij
Don't import head revision twice when pulling from Git.
484
            if o.object[1] not in checked:
485
                heads.append(o.object[1])
0.200.296 by Jelmer Vernooij
Avoid iterating over all objects just to find the *Commits* to retrieve.
486
        else:
487
            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.
488
        checked.add(o.id)
489
    del checked
0.200.158 by Jelmer Vernooij
fetch works \o/
490
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
491
    # Create the inventory objects
0.200.821 by Jelmer Vernooij
Remove last references to ID.children.
492
    batch_size = 1000
0.200.680 by Jelmer Vernooij
fetch revisions in batches
493
    revision_ids = topo_sort(graph)
494
    pack_hints = []
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
495
    if limit is not None:
496
        revision_ids = revision_ids[:limit]
0.247.3 by Michael Hudson
oh, so it wasn't (particularly) wrong, but it was a bit obscure
497
    last_imported = None
0.200.680 by Jelmer Vernooij
fetch revisions in batches
498
    for offset in range(0, len(revision_ids), batch_size):
0.254.33 by Jelmer Vernooij
Merge trunk.
499
        target_git_object_retriever.start_write_group() 
0.200.680 by Jelmer Vernooij
fetch revisions in batches
500
        try:
0.254.33 by Jelmer Vernooij
Merge trunk.
501
            repo.start_write_group()
502
            try:
0.200.824 by Jelmer Vernooij
Commit cache data in batches as well.
503
                for i, head in enumerate(
504
                    revision_ids[offset:offset+batch_size]):
0.254.33 by Jelmer Vernooij
Merge trunk.
505
                    if pb is not None:
0.200.824 by Jelmer Vernooij
Commit cache data in batches as well.
506
                        pb.update("fetching revisions", offset+i,
507
                                  len(revision_ids))
0.254.33 by Jelmer Vernooij
Merge trunk.
508
                    import_git_commit(repo, mapping, head, lookup_object,
0.252.25 by Jelmer Vernooij
Reformatting.
509
                        target_git_object_retriever, trees_cache)
0.254.33 by Jelmer Vernooij
Merge trunk.
510
                    last_imported = head
511
            except:
512
                repo.abort_write_group()
513
                raise
514
            else:
515
                hint = repo.commit_write_group()
516
                if hint is not None:
517
                    pack_hints.extend(hint)
0.200.680 by Jelmer Vernooij
fetch revisions in batches
518
        except:
0.254.33 by Jelmer Vernooij
Merge trunk.
519
            target_git_object_retriever.abort_write_group()
0.200.680 by Jelmer Vernooij
fetch revisions in batches
520
            raise
521
        else:
0.254.33 by Jelmer Vernooij
Merge trunk.
522
            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
523
    return pack_hints, last_imported
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
524
525
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
526
class InterFromGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
527
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
528
    _matching_repo_format = GitRepositoryFormat()
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
529
0.200.1154 by Jelmer Vernooij
Share more code in InterGitRepository.
530
    def _target_has_shas(self, shas):
531
        raise NotImplementedError(self._target_has_shas)
532
533
    def get_determine_wants_heads(self, wants, include_tags=False):
534
        wants = set(wants)
535
        def determine_wants(refs):
536
            potential = set(wants)
537
            if include_tags:
0.200.1300 by Jelmer Vernooij
Fix formatting.
538
                potential.update(
539
                    [v[1] or v[0] for v in extract_tags(refs).itervalues()])
0.200.1154 by Jelmer Vernooij
Share more code in InterGitRepository.
540
            return list(potential - self._target_has_shas(potential))
541
        return determine_wants
542
543
    def determine_wants_all(self, refs):
0.200.1300 by Jelmer Vernooij
Fix formatting.
544
        potential = set([sha for (ref, sha) in refs.iteritems() if not
545
            ref.endswith("^{}")])
0.200.1154 by Jelmer Vernooij
Share more code in InterGitRepository.
546
        return list(potential - self._target_has_shas(potential))
547
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
548
    @staticmethod
549
    def _get_repo_format_to_test():
550
        return None
551
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
552
    def copy_content(self, revision_id=None, pb=None):
553
        """See InterRepository.copy_content."""
554
        self.fetch(revision_id, pb, find_ghosts=False)
555
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
556
    def search_missing_revision_ids(self,
557
            find_ghosts=True, revision_ids=None, if_present_ids=None,
558
            limit=None):
559
        git_shas = []
560
        todo = []
561
        if revision_ids:
562
            todo.extend(revision_ids)
563
        if if_present_ids:
564
            todo.extend(revision_ids)
565
        for revid in revision_ids:
566
            if revid == NULL_REVISION:
567
                continue
568
            git_sha, mapping = self.source.lookup_bzr_revision_id(revid)
569
            git_shas.append(git_sha)
570
        walker = Walker(self.source._git.object_store,
571
            include=git_shas, exclude=[sha for sha in self.target._git.get_refs().values() if sha != ZERO_SHA])
572
        missing_revids = set()
573
        for entry in walker:
574
            missing_revids.add(self.source.lookup_foreign_revision_id(entry.commit.id))
575
        return self.source.revision_ids_to_search_result(missing_revids)
576
577
578
class InterGitNonGitRepository(InterFromGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
579
    """Base InterRepository that copies revisions from a Git into a non-Git
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
580
    repository."""
581
0.259.4 by Jelmer Vernooij
Put determine_wants methods on InterRepo.
582
    def _target_has_shas(self, shas):
0.200.1403 by Jelmer Vernooij
Cope with tags pointing at tree objects when cloning local git repositories.
583
        revids = []
584
        for sha in shas:
585
            try:
586
                revid = self.source.lookup_foreign_revision_id(sha)
587
            except NotCommitError:
588
                continue
589
            else:
590
                revids.append(revid)
0.259.4 by Jelmer Vernooij
Put determine_wants methods on InterRepo.
591
        return self.target.has_revisions(revids)
592
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
593
    def get_determine_wants_revids(self, revids, include_tags=False):
594
        wants = set()
595
        for revid in set(revids):
0.200.1388 by Jelmer Vernooij
Don't fetch revision already present.
596
            if self.target.has_revision(revid):
597
                continue
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
598
            git_sha, mapping = self.source.lookup_bzr_revision_id(revid)
599
            wants.add(git_sha)
0.200.1309 by Jelmer Vernooij
Break some more long lines.
600
        return self.get_determine_wants_heads(wants,
601
            include_tags=include_tags)
0.259.6 by Jelmer Vernooij
Fetch tags during pull.
602
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
603
    def fetch_objects(self, determine_wants, mapping, pb=None, limit=None):
604
        """Fetch objects from a remote server.
605
606
        :param determine_wants: determine_wants callback
607
        :param mapping: BzrGitMapping to use
608
        :param pb: Optional progress bar
609
        :param limit: Maximum number of commits to import.
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
610
        :return: Tuple with pack hint, last imported revision id and remote refs
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
611
        """
612
        raise NotImplementedError(self.fetch_objects)
613
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
614
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
0.200.247 by Jelmer Vernooij
Fix git-import.
615
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
616
        if mapping is None:
617
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
618
        if revision_id is not None:
619
            interesting_heads = [revision_id]
620
        elif fetch_spec is not None:
0.200.1089 by Jelmer Vernooij
Cope with fancy fetch_spec behaviour.
621
            recipe = fetch_spec.get_recipe()
622
            if recipe[0] in ("search", "proxy-search"):
623
                interesting_heads = recipe[1]
624
            else:
0.200.1300 by Jelmer Vernooij
Fix formatting.
625
                raise AssertionError("Unsupported search result type %s" %
626
                        recipe[0])
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
627
        else:
628
            interesting_heads = None
0.259.4 by Jelmer Vernooij
Put determine_wants methods on InterRepo.
629
630
        if interesting_heads is not None:
0.200.1309 by Jelmer Vernooij
Break some more long lines.
631
            determine_wants = self.get_determine_wants_revids(
632
                interesting_heads, include_tags=False)
0.259.4 by Jelmer Vernooij
Put determine_wants methods on InterRepo.
633
        else:
634
            determine_wants = self.determine_wants_all
0.200.1079 by Jelmer Vernooij
Avoid looking up revid if not necessary.
635
636
        (pack_hint, _, remote_refs) = self.fetch_objects(determine_wants,
637
            mapping, pb)
0.200.579 by Jelmer Vernooij
Only pack if it makes the target repo smaller.
638
        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.
639
            self.target.pack(hint=pack_hint)
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
640
        assert isinstance(remote_refs, dict)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
641
        return remote_refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
642
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
643
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
644
_GIT_PROGRESS_RE = re.compile(r"(.*?): +(\d+)% \((\d+)/(\d+)\)")
645
def report_git_progress(pb, text):
646
    text = text.rstrip("\r\n")
647
    g = _GIT_PROGRESS_RE.match(text)
648
    if g is not None:
649
        (text, pct, current, total) = g.groups()
650
        pb.update(text, int(current), int(total))
651
    else:
652
        pb.update(text, 0, 0)
653
654
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
655
class DetermineWantsRecorder(object):
656
657
    def __init__(self, actual):
658
        self.actual = actual
659
        self.wants = []
660
        self.remote_refs = {}
661
662
    def __call__(self, refs):
663
        self.remote_refs = refs
664
        self.wants = self.actual(refs)
665
        return self.wants
666
667
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
668
class InterRemoteGitNonGitRepository(InterGitNonGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
669
    """InterRepository that copies revisions from a remote Git into a non-Git
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
670
    repository."""
671
0.200.582 by Jelmer Vernooij
Use more efficient algorithm for finding out heads.
672
    def get_target_heads(self):
673
        # FIXME: This should be more efficient
674
        all_revs = self.target.all_revision_ids()
675
        parent_map = self.target.get_parent_map(all_revs)
676
        all_parents = set()
677
        map(all_parents.update, parent_map.itervalues())
678
        return set(all_revs) - all_parents
679
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
680
    def fetch_objects(self, determine_wants, mapping, pb=None, limit=None):
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
681
        """See `InterGitNonGitRepository`."""
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
682
        def progress(text):
0.200.563 by Jelmer Vernooij
Attempt to parse progress indication from git status reports.
683
            report_git_progress(pb, text)
0.200.466 by Jelmer Vernooij
Fix finding of heads for fetch_objects.
684
        store = BazaarObjectStore(self.target, mapping)
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
685
        store.lock_write()
0.200.465 by Jelmer Vernooij
Use dulwich standard functionality for finding missing revisions.
686
        try:
0.200.582 by Jelmer Vernooij
Use more efficient algorithm for finding out heads.
687
            heads = self.get_target_heads()
0.200.484 by Jelmer Vernooij
Cope with kind changes.
688
            graph_walker = store.get_graph_walker(
689
                    [store._lookup_revision_sha1(head) for head in heads])
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
690
            wants_recorder = DetermineWantsRecorder(determine_wants)
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
691
0.200.484 by Jelmer Vernooij
Cope with kind changes.
692
            create_pb = None
693
            if pb is None:
694
                create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
695
            try:
0.200.1000 by Jelmer Vernooij
Fix fetch between local and remote git branches.
696
                objects_iter = self.source.fetch_objects(
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
697
                    wants_recorder, graph_walker, store.get_raw,
0.200.1000 by Jelmer Vernooij
Fix fetch between local and remote git branches.
698
                    progress)
0.200.1300 by Jelmer Vernooij
Fix formatting.
699
                trace.mutter("Importing %d new revisions",
700
                             len(wants_recorder.wants))
701
                (pack_hint, last_rev) = import_git_objects(self.target,
702
                    mapping, objects_iter, store, wants_recorder.wants, pb,
703
                    limit)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
704
                return (pack_hint, last_rev, wants_recorder.remote_refs)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
705
            finally:
0.200.484 by Jelmer Vernooij
Cope with kind changes.
706
                if create_pb:
707
                    create_pb.finished()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
708
        finally:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
709
            store.unlock()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
710
711
    @staticmethod
712
    def is_compatible(source, target):
713
        """Be compatible with GitRepository."""
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
714
        if not isinstance(source, RemoteGitRepository):
715
            return False
716
        if not target.supports_rich_root():
717
            return False
718
        if isinstance(target, GitRepository):
719
            return False
0.200.1270 by Jelmer Vernooij
Cope with older versions of bzr.
720
        if not getattr(target._format, "supports_full_versioned_files", True):
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
721
            return False
722
        return True
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
723
724
725
class InterLocalGitNonGitRepository(InterGitNonGitRepository):
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
726
    """InterRepository that copies revisions from a local Git into a non-Git
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
727
    repository."""
728
0.247.2 by Michael Hudson
this works for my tests, but i'm pretty sure it's wrong in general
729
    def fetch_objects(self, determine_wants, mapping, pb=None, limit=None):
0.200.1001 by Jelmer Vernooij
Simplify handling of determine wants, add stub for fetch_objects().
730
        """See `InterGitNonGitRepository`."""
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
731
        remote_refs = self.source._git.get_refs()
732
        wants = determine_wants(remote_refs)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
733
        create_pb = None
734
        if pb is None:
735
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
736
        target_git_object_retriever = BazaarObjectStore(self.target, mapping)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
737
        try:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
738
            target_git_object_retriever.lock_write()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
739
            try:
0.200.1300 by Jelmer Vernooij
Fix formatting.
740
                (pack_hint, last_rev) = import_git_objects(self.target,
741
                    mapping, self.source._git.object_store,
0.248.5 by Jelmer Vernooij
Reformatting, fix dpush.
742
                    target_git_object_retriever, wants, pb, limit)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
743
                return (pack_hint, last_rev, remote_refs)
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
744
            finally:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
745
                target_git_object_retriever.unlock()
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
746
        finally:
747
            if create_pb:
748
                create_pb.finished()
749
750
    @staticmethod
751
    def is_compatible(source, target):
752
        """Be compatible with GitRepository."""
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
753
        if not isinstance(source, LocalGitRepository):
754
            return False
755
        if not target.supports_rich_root():
756
            return False
757
        if isinstance(target, GitRepository):
758
            return False
0.200.1266 by Jelmer Vernooij
Fix 2.3 support.
759
        if not getattr(target._format, "supports_full_versioned_files", True):
0.200.1222 by Jelmer Vernooij
Better checks in is_compatible methods.
760
            return False
761
        return True
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
762
763
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
764
class InterGitGitRepository(InterFromGitRepository):
0.200.291 by Jelmer Vernooij
Print proper error about not supporting push.
765
    """InterRepository that copies between Git repositories."""
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
766
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
767
    def fetch_objects(self, determine_wants, mapping, pb=None):
768
        def progress(text):
769
            trace.note("git: %s", text)
770
        graphwalker = self.target._git.get_graph_walker()
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
771
        if (isinstance(self.source, LocalGitRepository) and
772
            isinstance(self.target, LocalGitRepository)):
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
773
            refs = self.source._git.fetch(self.target._git, determine_wants,
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
774
                progress)
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
775
            return (None, None, refs)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
776
        elif (isinstance(self.source, LocalGitRepository) and
777
              isinstance(self.target, RemoteGitRepository)):
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
778
            raise NotImplementedError
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
779
        elif (isinstance(self.source, RemoteGitRepository) and
780
              isinstance(self.target, LocalGitRepository)):
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
781
            f, commit = self.target._git.object_store.add_thin_pack()
782
            try:
0.200.1003 by Jelmer Vernooij
Initial work on supporting move_in_thin_pack.
783
                refs = self.source.bzrdir.root_transport.fetch_pack(
784
                    determine_wants, graphwalker, f.write, progress)
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
785
                commit()
0.200.1002 by Jelmer Vernooij
Fix regression in git-import.
786
                return (None, None, refs)
0.200.635 by Jelmer Vernooij
Fix fetching between git repositories.
787
            except:
788
                f.close()
789
                raise
790
        else:
791
            raise AssertionError
792
0.200.1154 by Jelmer Vernooij
Share more code in InterGitRepository.
793
    def _target_has_shas(self, shas):
794
        return set([sha for sha in shas if self.target._git.object_store])
795
0.200.940 by Jelmer Vernooij
Avoid confusion between different fetch functions with different semantics.
796
    def fetch(self, revision_id=None, pb=None, find_ghosts=False,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
797
              mapping=None, fetch_spec=None, branches=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
798
        if mapping is None:
799
            mapping = self.source.get_mapping()
800
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
801
        if revision_id is not None:
0.200.1324 by Jelmer Vernooij
More work on roundtripping support.
802
            args = [self.source.lookup_bzr_revision_id(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
803
        elif fetch_spec is not None:
0.200.1089 by Jelmer Vernooij
Cope with fancy fetch_spec behaviour.
804
            recipe = fetch_spec.get_recipe()
805
            if recipe[0] in ("search", "proxy-search"):
806
                heads = recipe[1]
807
            else:
0.200.1309 by Jelmer Vernooij
Break some more long lines.
808
                raise AssertionError(
809
                    "Unsupported search result type %s" % recipe[0])
0.200.1350 by Jelmer Vernooij
Implement search_missing_revision_ids.
810
            args = [self.source.lookup_bzr_revision_id(revid)[0] for revid in heads]
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
811
        if branches is not None:
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
812
            determine_wants = lambda x: [x[y] for y in branches if not x[y] in r.object_store and x[y] != ZERO_SHA]
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
813
        elif fetch_spec is None and revision_id is None:
0.200.1154 by Jelmer Vernooij
Share more code in InterGitRepository.
814
            determine_wants = self.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
815
        else:
0.200.1176 by Jelmer Vernooij
Fix fetch return value for inter git fetching.
816
            determine_wants = lambda x: [y for y in args if not y in r.object_store and y != ZERO_SHA]
817
        wants_recorder = DetermineWantsRecorder(determine_wants)
818
        self.fetch_objects(wants_recorder, mapping)
819
        return wants_recorder.remote_refs
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
820
821
    @staticmethod
822
    def is_compatible(source, target):
823
        """Be compatible with GitRepository."""
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
824
        return (isinstance(source, GitRepository) and
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
825
                isinstance(target, GitRepository))
0.200.1174 by Jelmer Vernooij
Fix specific revision fetching between git repositories.
826
827
    def get_determine_wants_revids(self, revids, include_tags=False):
828
        wants = set()
829
        for revid in set(revids):
0.200.1388 by Jelmer Vernooij
Don't fetch revision already present.
830
            if self.target.has_revision(revid):
831
                continue
0.200.1174 by Jelmer Vernooij
Fix specific revision fetching between git repositories.
832
            git_sha, mapping = self.source.lookup_bzr_revision_id(revid)
833
            wants.add(git_sha)
0.200.1309 by Jelmer Vernooij
Break some more long lines.
834
        return self.get_determine_wants_heads(wants,
835
            include_tags=include_tags)