177
def directory_to_tree(path, children, lookup_ie_sha1, unusual_modes, empty_file_name,
179
"""Create a Git Tree object from a Bazaar directory.
181
:param path: directory path
182
:param children: Children inventory entries
183
:param lookup_ie_sha1: Lookup the Git SHA1 for a inventory entry
184
:param unusual_modes: Dictionary with unusual file modes by file ids
185
:param empty_file_name: Name to use for dummy files in empty directories,
186
None to ignore empty directories.
189
for value in children:
190
if value.name in BANNED_FILENAMES:
192
child_path = osutils.pathjoin(path, value.name)
194
mode = unusual_modes[child_path]
196
mode = entry_mode(value)
197
hexsha = lookup_ie_sha1(child_path, value)
198
if hexsha is not None:
199
tree.add(value.name.encode("utf-8"), mode, hexsha)
200
if not allow_empty and len(tree) == 0:
201
# Only the root can be an empty tree
202
if empty_file_name is not None:
203
tree.add(empty_file_name, stat.S_IFREG | 0644, Blob().id)
171
209
def _tree_to_objects(tree, parent_trees, idmap, unusual_modes,
172
dummy_file_name=None):
210
dummy_file_name=None, add_cache_entry=None):
173
211
"""Iterate over the objects that were introduced in a revision.
175
213
:param idmap: id map
209
248
# Find all the changed blobs
210
249
for (file_id, path, changed_content, versioned, parent, name, kind,
211
250
executable) in tree.iter_changes(base_tree):
251
if name[1] in BANNED_FILENAMES:
212
253
if kind[1] == "file":
254
sha1 = tree.get_file_sha1(path[1], file_id)
257
(pfile_id, prevision) = find_unchanged_parent_ie(file_id, kind[1], sha1, other_parent_trees)
261
# It existed in one of the parents, with the same contents.
262
# So no need to yield any new git objects.
215
(pfile_id, prevision) = find_unchanged_parent_ie(file_id, kind[1], tree.get_file_sha1(path[1], file_id), other_parent_trees)
264
blob_id = idmap.lookup_blob_id(
220
shamap[file_id] = idmap.lookup_blob_id(
267
if not changed_content:
223
268
# no-change merge ?
225
270
blob.data = tree.get_file_text(path[1], file_id)
226
shamap[file_id] = blob.id
227
if not file_id in shamap:
228
273
new_blobs.append((path[1], file_id))
275
shamap[path[1]] = blob_id
276
if add_cache_entry is not None:
277
add_cache_entry(("blob", blob_id), (file_id, tree.get_file_revision(path[1])), path[1])
229
278
elif kind[1] == "symlink":
231
target = tree.get_symlink_target(path[1], file_id)
232
blob = symlink_to_blob(target)
233
shamap[file_id] = blob.id
235
find_unchanged_parent_ie(file_id, kind[1], target, other_parent_trees)
279
target = tree.get_symlink_target(path[1], file_id)
280
blob = symlink_to_blob(target)
281
shamap[path[1]] = blob.id
282
if add_cache_entry is not None:
283
add_cache_entry(blob, (file_id, tree.get_file_revision(path[1])), path[1])
285
find_unchanged_parent_ie(file_id, kind[1], target, other_parent_trees)
237
288
yield path[1], blob, (file_id, tree.get_file_revision(path[1], file_id))
238
elif kind[1] not in (None, "directory"):
289
elif kind[1] is None:
290
shamap[path[1]] = None
291
elif kind[1] != 'directory':
239
292
raise AssertionError(kind[1])
241
if p and tree.has_id(p) and tree.kind(tree.id2path(p)) == "directory":
296
dirty_dirs.add(osutils.dirname(p))
244
298
# Fetch contents of the blobs that were changed
245
299
for (path, file_id), chunks in tree.iter_files_bytes(
246
300
[(path, (path, file_id)) for (path, file_id) in new_blobs]):
248
302
obj.chunked = chunks
303
if add_cache_entry is not None:
304
add_cache_entry(obj, (file_id, tree.get_file_revision(path)), path)
249
305
yield path, obj, (file_id, tree.get_file_revision(path, file_id))
250
shamap[file_id] = obj.id
306
shamap[path] = obj.id
252
308
for path in unusual_modes:
253
parent_path = posixpath.dirname(path)
254
file_id = tree.path2id(parent_path)
256
raise AssertionError("Unable to find file id for %r" % parent_path)
257
dirty_dirs.add(file_id)
260
inv = tree.root_inventory
261
except AttributeError:
267
for file_id in dirty_dirs:
268
if file_id is None or not inv.has_id(file_id):
270
trees[inv.id2path(file_id)] = file_id
271
ie = inv.get_entry(file_id)
272
if ie.parent_id is not None:
273
new_dirs.add(ie.parent_id)
274
dirty_dirs = new_dirs
276
def ie_to_hexsha(ie):
309
dirty_dirs.add(posixpath.dirname(path))
311
for dir in list(dirty_dirs):
312
for parent in osutils.parent_directories(dir):
313
if parent in dirty_dirs:
315
dirty_dirs.add(parent)
320
def ie_to_hexsha(path, ie):
278
return shamap[ie.file_id]
280
# FIXME: Should be the same as in parent
281
if ie.kind in ("file", "symlink"):
283
return idmap.lookup_blob_id(ie.file_id, ie.revision)
287
path = tree.id2path(ie.file_id)
288
blob.data = tree.get_file_text(path, ie.file_id)
290
elif ie.kind == "directory":
291
# Not all cache backends store the tree information,
292
# calculate again from scratch
293
ret = directory_to_tree(ie.children, ie_to_hexsha,
294
unusual_modes, dummy_file_name, ie.parent_id is None)
301
for path in sorted(trees.keys(), reverse=True):
302
file_id = trees[path]
303
if tree.kind(path, file_id) != 'directory':
305
ie = inv.get_entry(file_id)
306
obj = directory_to_tree(ie.children, ie_to_hexsha, unusual_modes,
307
dummy_file_name, path == "")
309
yield path, obj, (file_id, )
310
shamap[file_id] = obj.id
325
# FIXME: Should be the same as in parent
326
if ie.kind in ("file", "symlink"):
328
return idmap.lookup_blob_id(ie.file_id, ie.revision)
332
blob.data = tree.get_file_text(path, ie.file_id)
333
if add_cache_entry is not None:
334
add_cache_entry(blob, (ie.file_id, ie.revision), path)
336
elif ie.kind == "directory":
337
# Not all cache backends store the tree information,
338
# calculate again from scratch
339
ret = directory_to_tree(path, ie.children.values(), ie_to_hexsha,
340
unusual_modes, dummy_file_name, ie.parent_id is None)
347
for path in sorted(dirty_dirs, reverse=True):
348
if not tree.has_filename(path):
351
if tree.kind(path) != 'directory':
355
for value in tree.iter_child_entries(path):
356
if value.name in BANNED_FILENAMES:
357
trace.warning('not exporting %s with banned filename %s',
358
value.kind, value.name)
360
child_path = osutils.pathjoin(path, value.name)
362
mode = unusual_modes[child_path]
364
mode = entry_mode(value)
365
hexsha = ie_to_hexsha(child_path, value)
366
if hexsha is not None:
367
obj.add(value.name.encode("utf-8"), mode, hexsha)
370
file_id = tree.path2id(path)
371
if add_cache_entry is not None:
372
add_cache_entry(obj, (file_id, tree.get_revision_id()), path)
373
yield path, obj, (file_id, tree.get_revision_id())
374
shamap[path] = obj.id
313
377
class PackTupleIterable(object):