464
464
specified_path_ids = _find_ids_across_trees(filenames, trees,
465
465
require_versioned)
466
466
return _find_children_across_trees(specified_path_ids, trees)
467
# specified_ids = [id for path, id in _find_path_ids_across_trees(filenames, trees, require_versioned)]
468
# return _find_children_across_trees(specified_ids, trees)
470
def find_path_ids_across_trees(filenames, trees, require_versioned=True):
471
"""Find the paths and ids corresponding to specified filenames.
473
All matches in all trees will be used, and all children of matched
474
directories will be included
476
:param filenames: The filenames to find file_ids for
477
:param trees: The trees to find file_ids within
478
:param require_versioned: if true, all specified filenames must occur in
480
:return: a set of (path, file ids) for the specified filenames and their
481
children. The returned path is the path of the id in the first tree
482
that contains it. This matters when files have been moved
486
# This function needs to know the ids for filenames in all trees, then
487
# search for those same files and children in all the other trees.
488
# it is complicated by the same path in two trees being able to have
489
# different ids, which might both be present in both trees.
490
# consider two trees, which have had 'mv foo bar' and 'mv baz foo' done
491
# in this case, a diff of 'foo' should should changes to both the current
492
# 'bar' and the current 'foo' which was baz. Its arguable that if
493
# the situation is 'mv parent/foo bar' and 'mv baz parent/foo', that
494
# we should return the current bar and the current parent/foo' - at the
495
# moment we do, but we loop around all ids and all trees: I*T checks.
497
# Updating this algorithm to be fast in the common case:
498
# nothing has moved, all files have the same id in parent, child and there
499
# are only two trees (or one is working tree and the others are parents).
500
# walk the dirstate. as we find each path, gather the paths of that
501
# id in all trees. add a mapping from the id to the path in those trees.
502
# now lookup children by id, again in all trees; for these trees that
503
# nothing has moved in, the id->path mapping will allow us to find the
504
# parent trivially. To answer 'has anything been moved' in one of the
505
# dirstate parent trees though, we will need to stare harder at it.
507
# Now, given a path index, that is trivial for any one tree, and given
508
# that we can ask for additional data from a dirstate tree, its a single
509
# pass, though it will require scanning the entire tree to find paths
510
# that were at the current location.
511
# ideal results?: There are three things: tree, path, id. Pathologically
512
# we can have completely disjoint ids for each tree; but we cannot have
513
# disjoin paths for each tree, except if we scan each tree for the
514
# different ids from other trees.
516
specified_path_ids = _find_ids_across_trees(filenames, trees,
518
return _find_path_id_children_across_trees(specified_path_ids, trees)
521
469
def _find_ids_across_trees(filenames, trees, require_versioned):