| 2906 | } |
| 2907 | |
| 2908 | static int update_submodules(struct update_data *update_data) |
| 2909 | { |
| 2910 | int i, ret = 0; |
| 2911 | struct submodule_update_clone suc = SUBMODULE_UPDATE_CLONE_INIT; |
| 2912 | const struct run_process_parallel_opts opts = { |
| 2913 | .tr2_category = "submodule", |
| 2914 | .tr2_label = "parallel/update", |
| 2915 | |
| 2916 | .processes = update_data->max_jobs, |
| 2917 | |
| 2918 | .get_next_task = update_clone_get_next_task, |
| 2919 | .start_failure = update_clone_start_failure, |
| 2920 | .task_finished = update_clone_task_finished, |
| 2921 | .data = &suc, |
| 2922 | }; |
| 2923 | |
| 2924 | suc.update_data = update_data; |
| 2925 | run_processes_parallel(&opts); |
| 2926 | |
| 2927 | /* |
| 2928 | * We saved the output and put it out all at once now. |
| 2929 | * That means: |
| 2930 | * - the listener does not have to interleave their (checkout) |
| 2931 | * work with our fetching. The writes involved in a |
| 2932 | * checkout involve more straightforward sequential I/O. |
| 2933 | * - the listener can avoid doing any work if fetching failed. |
| 2934 | */ |
| 2935 | if (suc.quickstop) { |
| 2936 | ret = 1; |
| 2937 | goto cleanup; |
| 2938 | } |
| 2939 | |
| 2940 | for (i = 0; i < suc.update_clone_nr; i++) { |
| 2941 | struct update_clone_data ucd = suc.update_clone[i]; |
| 2942 | int code = 128; |
| 2943 | |
| 2944 | oidcpy(&update_data->oid, &ucd.oid); |
| 2945 | update_data->just_cloned = ucd.just_cloned; |
| 2946 | update_data->sm_path = ucd.sub->path; |
| 2947 | |
| 2948 | /* |
| 2949 | * Verify that the submodule path does not contain any |
| 2950 | * symlinks; if it does, it might have been tampered with. |
| 2951 | * TODO: allow exempting it via |
| 2952 | * `safe.submodule.path` or something |
| 2953 | */ |
| 2954 | if (validate_submodule_path(update_data->sm_path) < 0) |
| 2955 | goto fail; |
| 2956 | |
| 2957 | code = ensure_core_worktree(update_data->sm_path); |
| 2958 | if (code) |
| 2959 | goto fail; |
| 2960 | |
| 2961 | update_data->displaypath = get_submodule_displaypath( |
| 2962 | update_data->sm_path, update_data->prefix, |
| 2963 | update_data->super_prefix); |
| 2964 | code = update_submodule(update_data); |
| 2965 | FREE_AND_NULL(update_data->displaypath); |
no test coverage detected