* Given the configuration of 'info', walk the commits based on 'info->revs' and * call 'info->path_fn' on each discovered path. * * Returns nonzero on an error. */
| 695 | * Returns nonzero on an error. |
| 696 | */ |
| 697 | int walk_objects_by_path(struct path_walk_info *info) |
| 698 | { |
| 699 | int ret; |
| 700 | size_t commits_nr = 0, paths_nr = 0; |
| 701 | struct commit *c; |
| 702 | struct type_and_oid_list *root_tree_list; |
| 703 | struct type_and_oid_list *commit_list; |
| 704 | struct path_walk_context ctx = { |
| 705 | .repo = info->revs->repo, |
| 706 | .revs = info->revs, |
| 707 | .info = info, |
| 708 | .path_stack = { |
| 709 | .compare = compare_by_type, |
| 710 | .cb_data = &ctx |
| 711 | }, |
| 712 | .path_stack_pushed = STRSET_INIT, |
| 713 | .paths_to_lists = STRMAP_INIT |
| 714 | }; |
| 715 | |
| 716 | trace2_region_enter("path-walk", "commit-walk", info->revs->repo); |
| 717 | |
| 718 | if (!prepare_filters(info, &info->revs->filter)) |
| 719 | return -1; |
| 720 | |
| 721 | CALLOC_ARRAY(commit_list, 1); |
| 722 | commit_list->type = OBJ_COMMIT; |
| 723 | |
| 724 | if (info->tags) |
| 725 | info->revs->tag_objects = 1; |
| 726 | |
| 727 | if (ctx.revs->prune_data.nr) { |
| 728 | if (!ctx.revs->prune_data.has_wildcard && |
| 729 | !ctx.revs->prune_data.magic) |
| 730 | ctx.exact_pathspecs = 1; |
| 731 | } |
| 732 | |
| 733 | /* Insert a single list for the root tree into the paths. */ |
| 734 | CALLOC_ARRAY(root_tree_list, 1); |
| 735 | root_tree_list->type = OBJ_TREE; |
| 736 | root_tree_list->maybe_interesting = 1; |
| 737 | strmap_put(&ctx.paths_to_lists, root_path, root_tree_list); |
| 738 | push_to_stack(&ctx, root_path); |
| 739 | |
| 740 | /* |
| 741 | * Ensure that prepare_revision_walk() keeps all pending objects |
| 742 | * even through an object type filter. |
| 743 | */ |
| 744 | info->revs->blob_objects = info->revs->tree_objects = 1; |
| 745 | |
| 746 | if (prepare_revision_walk(info->revs)) |
| 747 | die(_("failed to setup revision walk")); |
| 748 | |
| 749 | info->revs->blob_objects = info->blobs; |
| 750 | info->revs->tree_objects = info->trees; |
| 751 | |
| 752 | /* |
| 753 | * Walk trees to mark them as UNINTERESTING. |
| 754 | * This is particularly important when 'edge_aggressive' is set. |