commit 14c901f1f8f27565b91c2e8a74939c74250d8521 from: Stefan Sperling date: Thu Aug 08 07:25:49 2019 UTC split up worktree.c's merge_blob() into merge_blob() and merge_file() commit - f5a17245fd8503e5cd7c2d1dd464c8a435e83463 commit + 14c901f1f8f27565b91c2e8a74939c74250d8521 blob - 56705cf058d3318856aad68700fbc380ab11e23d blob + 04dedb5234881a9d6726e1e8da27d6eb707ceaaa --- lib/worktree.c +++ lib/worktree.c @@ -719,24 +719,21 @@ done: /* * Perform a 3-way merge where blob_orig acts as the common ancestor, - * blob_deriv acts as the first derived version, and the file on disk - * acts as the second derived version. + * the file at deriv_path acts as the first derived version, and the + * file on disk acts as the second derived version. */ static const struct got_error * -merge_blob(int *local_changes_subsumed, struct got_worktree *worktree, +merge_file(int *local_changes_subsumed, struct got_worktree *worktree, struct got_blob_object *blob_orig, const char *ondisk_path, - const char *path, uint16_t st_mode, struct got_blob_object *blob_deriv, - struct got_object_id *deriv_base_commit_id, - struct got_repository *repo, got_worktree_checkout_cb progress_cb, - void *progress_arg) + const char *path, uint16_t st_mode, const char *deriv_path, + const char *label_deriv, struct got_repository *repo, + got_worktree_checkout_cb progress_cb, void *progress_arg) { const struct got_error *err = NULL; int merged_fd = -1; - FILE *f_deriv = NULL, *f_orig = NULL; - char *blob_deriv_path = NULL, *blob_orig_path = NULL; + FILE *f_orig = NULL; + char *blob_orig_path = NULL; char *merged_path = NULL, *base_path = NULL; - char *id_str = NULL; - char *label_deriv = NULL; int overlapcnt = 0; char *parent; @@ -750,23 +747,8 @@ merge_blob(int *local_changes_subsumed, struct got_wor return got_error_from_errno("asprintf"); err = got_opentemp_named_fd(&merged_path, &merged_fd, base_path); - if (err) - goto done; - - free(base_path); - if (asprintf(&base_path, "%s/got-merge-blob-deriv", parent) == -1) { - err = got_error_from_errno("asprintf"); - base_path = NULL; - goto done; - } - - err = got_opentemp_named(&blob_deriv_path, &f_deriv, base_path); if (err) goto done; - err = got_object_blob_dump_to_file(NULL, NULL, NULL, f_deriv, - blob_deriv); - if (err) - goto done; free(base_path); if (asprintf(&base_path, "%s/got-merge-blob-orig", parent) == -1) { @@ -791,15 +773,7 @@ merge_blob(int *local_changes_subsumed, struct got_wor */ } - err = got_object_id_str(&id_str, deriv_base_commit_id); - if (err) - goto done; - if (asprintf(&label_deriv, "commit %s", id_str) == -1) { - err = got_error_from_errno("asprintf"); - goto done; - } - - err = got_merge_diff3(&overlapcnt, merged_fd, blob_deriv_path, + err = got_merge_diff3(&overlapcnt, merged_fd, deriv_path, blob_orig_path, ondisk_path, label_deriv, path); if (err) goto done; @@ -816,7 +790,7 @@ merge_blob(int *local_changes_subsumed, struct got_wor /* Check if a clean merge has subsumed all local changes. */ if (overlapcnt == 0) { - err = check_files_equal(local_changes_subsumed, blob_deriv_path, + err = check_files_equal(local_changes_subsumed, deriv_path, merged_path); if (err) goto done; @@ -837,20 +811,75 @@ merge_blob(int *local_changes_subsumed, struct got_wor done: if (merged_fd != -1 && close(merged_fd) != 0 && err == NULL) err = got_error_from_errno("close"); - if (f_deriv && fclose(f_deriv) != 0 && err == NULL) - err = got_error_from_errno("fclose"); if (f_orig && fclose(f_orig) != 0 && err == NULL) err = got_error_from_errno("fclose"); free(merged_path); free(base_path); - if (blob_deriv_path) { - unlink(blob_deriv_path); - free(blob_deriv_path); - } if (blob_orig_path) { unlink(blob_orig_path); free(blob_orig_path); } + return err; +} + +/* + * Perform a 3-way merge where blob_orig acts as the common ancestor, + * blob_deriv acts as the first derived version, and the file on disk + * acts as the second derived version. + */ +static const struct got_error * +merge_blob(int *local_changes_subsumed, struct got_worktree *worktree, + struct got_blob_object *blob_orig, const char *ondisk_path, + const char *path, uint16_t st_mode, struct got_blob_object *blob_deriv, + struct got_object_id *deriv_base_commit_id, + struct got_repository *repo, got_worktree_checkout_cb progress_cb, + void *progress_arg) +{ + const struct got_error *err = NULL; + FILE *f_deriv = NULL; + char *blob_deriv_path = NULL, *base_path = NULL, *id_str = NULL; + char *label_deriv = NULL, *parent; + + *local_changes_subsumed = 0; + + parent = dirname(ondisk_path); + if (parent == NULL) + return got_error_from_errno2("dirname", ondisk_path); + + free(base_path); + if (asprintf(&base_path, "%s/got-merge-blob-deriv", parent) == -1) { + err = got_error_from_errno("asprintf"); + base_path = NULL; + goto done; + } + + err = got_opentemp_named(&blob_deriv_path, &f_deriv, base_path); + if (err) + goto done; + err = got_object_blob_dump_to_file(NULL, NULL, NULL, f_deriv, + blob_deriv); + if (err) + goto done; + + err = got_object_id_str(&id_str, deriv_base_commit_id); + if (err) + goto done; + if (asprintf(&label_deriv, "commit %s", id_str) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + + err = merge_file(local_changes_subsumed, worktree, blob_orig, + ondisk_path, path, st_mode, blob_deriv_path, label_deriv, + repo, progress_cb, progress_arg); +done: + if (f_deriv && fclose(f_deriv) != 0 && err == NULL) + err = got_error_from_errno("fclose"); + free(base_path); + if (blob_deriv_path) { + unlink(blob_deriv_path); + free(blob_deriv_path); + } free(id_str); free(label_deriv); return err;