human
I wrote the below code

    all_parent_changes = [tree_changes(store, t, tree_id, rename_detector=rename_detector) for t in parent_tree_ids]
    num_parents = len(parent_tree_ids)
    changes_by_path = defaultdict((lambda : ([None] * num_parents)))
    for (i, parent_changes) in enumerate(all_parent_changes):
        for change in parent_changes:
            if (change.type == CHANGE_DELETE):
                path = change.old.path
            else:
                path = change.new.path
            changes_by_path[path][i] = change
    def old_sha(c):
        return c.old.sha
    def change_type(c):
        return c.type
    for (_, changes) in sorted(changes_by_path.items()):
        assert (len(changes) == num_parents)
        have = [c for c in changes if (c is not None)]
        if _all_eq(have, change_type, CHANGE_DELETE):
            if (not _all_same(have, old_sha)):
                (yield changes)
        elif (not _all_same(have, change_type)):
            (yield changes)
        elif (None not in changes):
            (yield changes)

What's a good function header?
assistant
#Here's a good function header.

def tree_changes_for_merge(store, parent_tree_ids, tree_id, rename_detector=None):