From: Stefan Sperling Subject: Re: histedit: How to fold M, D? To: Christian Weisgerber , gameoftrees@openbsd.org Date: Tue, 25 Jul 2023 15:49:32 +0200 On Tue, Jul 25, 2023 at 03:32:36PM +0200, Stefan Sperling wrote: > On Tue, Jul 25, 2023 at 03:24:16PM +0200, Stefan Sperling wrote: > > Below is a relatively simple patch you could try. > > Oh sorry this diff won't work as-is since it assumes that the > blob ID passed in already matches the file on disk. I will have > to revisit this, adding an object ID lookup. Try this one please. Also fixes small leaks in unlikely error paths. diff /home/stsp/src/got commit - 48bfa43b34c38fcf5e33c1e63dbe5dbd8c5865ce path + /home/stsp/src/got blob - c2e52f2b6af12e7f6d173ad130885b820fa1bd5e file + lib/worktree.c --- lib/worktree.c +++ lib/worktree.c @@ -2999,6 +2999,7 @@ merge_file_cb(void *arg, struct got_blob_object *blob1 int local_changes_subsumed; FILE *f_orig = NULL, *f_deriv = NULL, *f_deriv2 = NULL; char *id_str = NULL, *label_deriv2 = NULL; + struct got_object_id *id = NULL; if (blob1 && blob2) { ie = got_fileindex_entry_get(a->fileindex, path2, @@ -3124,19 +3125,37 @@ merge_file_cb(void *arg, struct got_blob_object *blob1 if (ie) got_fileindex_entry_mark_deleted_from_disk(ie); break; + case GOT_STATUS_MODIFY: case GOT_STATUS_ADD: { - struct got_object_id *id; FILE *blob1_f; off_t blob1_size; + int blob_found = 0; /* - * Delete the added file only if its content already + * Delete the file only if its content already * exists in the repository. */ err = got_object_blob_file_create(&id, &blob1_f, &blob1_size, path1); if (err) goto done; - if (got_object_id_cmp(id, id1) == 0) { + if (fclose(blob1_f) == EOF) { + err = got_error_from_errno("fclose"); + goto done; + } + if (status == GOT_STATUS_MODIFY) { + int obj_type; + + /* Implied existence check. */ + err = got_object_get_type(&obj_type, repo, id); + if (err) { + if (err->code != GOT_ERR_NO_OBJ) + goto done; + err = NULL; + } else if (obj_type == GOT_OBJ_TYPE_BLOB) + blob_found = 1; + } + if ((status == GOT_STATUS_ADD && + got_object_id_cmp(id, id1) == 0) || blob_found) { err = (*a->progress_cb)(a->progress_arg, GOT_STATUS_DELETE, path1); if (err) @@ -3152,14 +3171,10 @@ merge_file_cb(void *arg, struct got_blob_object *blob1 err = (*a->progress_cb)(a->progress_arg, GOT_STATUS_CANNOT_DELETE, path1); } - if (fclose(blob1_f) == EOF && err == NULL) - err = got_error_from_errno("fclose"); - free(id); if (err) goto done; break; } - case GOT_STATUS_MODIFY: case GOT_STATUS_CONFLICT: err = (*a->progress_cb)(a->progress_arg, GOT_STATUS_CANNOT_DELETE, path1); @@ -3243,6 +3258,7 @@ done: if (f_deriv2 && fclose(f_deriv2) == EOF && err == NULL) err = got_error_from_errno("fclose"); free(id_str); + free(id); free(label_deriv2); free(ondisk_path); return err;