commit cdbfe5d2325bd7ae7a197ce5e7a93fcdba9097cb from: Stefan Sperling date: Mon Jul 24 12:36:57 2023 UTC add cancellation support to the mixed-commits checker in worktree.c commit - 79c49d8454129776fe282b780f5836be20ea0052 commit + cdbfe5d2325bd7ae7a197ce5e7a93fcdba9097cb blob - dae05a53000410c2bf66f6696b63f8af1312036e blob + 72eb97a7e23d5f426a1660337c93deb7704985ad --- got/got.c +++ got/got.c @@ -6806,7 +6806,8 @@ list_branch(struct got_repository *repo, struct got_wo refname = got_ref_get_name(ref); if (worktree && strcmp(refname, got_worktree_get_head_ref_name(worktree)) == 0) { - err = got_worktree_get_state(&marker, repo, worktree); + err = got_worktree_get_state(&marker, repo, worktree, + check_cancelled, NULL); if (err != NULL) return err; } blob - 02e203f9626eba60a84658a1f9e7a8d0fb043418 blob + e45d7096cd1e609bd13f07ec1c9dcfcaf5a6b508 --- include/got_worktree.h +++ include/got_worktree.h @@ -140,7 +140,8 @@ const struct got_error *got_worktree_set_base_commit_i * GOT_WORKTREE_STATE_UPTODATE, else it will be GOT_WORKTREE_STATE_OUTOFDATE. */ const struct got_error *got_worktree_get_state(char *, - struct got_repository *, struct got_worktree *); + struct got_repository *, struct got_worktree *, + got_cancel_cb, void *); #define GOT_WORKTREE_STATE_UNKNOWN ' ' #define GOT_WORKTREE_STATE_UPTODATE '*' blob - e0c7318204bffd754947e3848dcb9e7b6ad3ae9e blob + 92a65f77687232bb4d27acbaae8e54b80258a589 --- lib/worktree.c +++ lib/worktree.c @@ -3236,15 +3236,28 @@ done: free(ondisk_path); return err; } + +struct check_mixed_commits_args { + struct got_worktree *worktree; + got_cancel_cb cancel_cb; + void *cancel_arg; +}; static const struct got_error * check_mixed_commits(void *arg, struct got_fileindex_entry *ie) { - struct got_worktree *worktree = arg; + const struct got_error *err; + struct check_mixed_commits_args *a = arg; + + if (a->cancel_cb) { + err = a->cancel_cb(a->cancel_arg); + if (err) + return err; + } /* Reject merges into a work tree with mixed base commits. */ if (got_fileindex_entry_has_commit(ie) && - memcmp(ie->commit_sha1, worktree->base_commit_id->sha1, + memcmp(ie->commit_sha1, a->worktree->base_commit_id->sha1, SHA1_DIGEST_LENGTH) != 0) return got_error(GOT_ERR_MIXED_COMMITS); @@ -3253,13 +3266,15 @@ check_mixed_commits(void *arg, struct got_fileindex_en const struct got_error * got_worktree_get_state(char *state, struct got_repository *repo, - struct got_worktree *worktree) + struct got_worktree *worktree, + got_cancel_cb cancel_cb, void *cancel_arg) { const struct got_error *err; struct got_object_id *base_id, *head_id = NULL; struct got_reference *head_ref; struct got_fileindex *fileindex = NULL; char *fileindex_path = NULL; + struct check_mixed_commits_args cma; if (worktree == NULL) return got_error(GOT_ERR_NOT_WORKTREE); @@ -3276,13 +3291,17 @@ got_worktree_get_state(char *state, struct got_reposit *state = GOT_WORKTREE_STATE_UNKNOWN; base_id = got_worktree_get_base_commit_id(worktree); + cma.worktree = worktree; + cma.cancel_cb = cancel_cb; + cma.cancel_arg = cancel_arg; + if (got_object_id_cmp(base_id, head_id) == 0) { err = open_fileindex(&fileindex, &fileindex_path, worktree); if (err) goto done; err = got_fileindex_for_each_entry_safe(fileindex, - check_mixed_commits, worktree); + check_mixed_commits, &cma); if (err == NULL) *state = GOT_WORKTREE_STATE_UPTODATE; else if (err->code == GOT_ERR_MIXED_COMMITS) { @@ -3480,6 +3499,7 @@ got_worktree_merge_files(struct got_worktree *worktree const struct got_error *err, *unlockerr; char *fileindex_path = NULL; struct got_fileindex *fileindex = NULL; + struct check_mixed_commits_args cma; err = lock_worktree(worktree, LOCK_EX); if (err) @@ -3489,8 +3509,12 @@ got_worktree_merge_files(struct got_worktree *worktree if (err) goto done; + cma.worktree = worktree; + cma.cancel_cb = cancel_cb; + cma.cancel_arg = cancel_arg; + err = got_fileindex_for_each_entry_safe(fileindex, check_mixed_commits, - worktree); + &cma); if (err) goto done; @@ -8407,11 +8431,16 @@ got_worktree_merge_branch(struct got_worktree *worktre { const struct got_error *err; char *fileindex_path = NULL; + struct check_mixed_commits_args cma; err = get_fileindex_path(&fileindex_path, worktree); if (err) goto done; + cma.worktree = worktree; + cma.cancel_cb = cancel_cb; + cma.cancel_arg = cancel_arg; + err = got_fileindex_for_each_entry_safe(fileindex, check_mixed_commits, worktree); if (err) blob - 1bd75430ffde37cc2e0c9ceb60677641c9813dc3 blob + c9d4b710fc2d07f40efd7711e09a36d698b9b3ce --- tog/tog.c +++ tog/tog.c @@ -3373,7 +3373,7 @@ log_thread(void *arg) goto done; } err = got_worktree_get_state(&tog_base_commit.marker, - a->repo, a->worktree); + a->repo, a->worktree, NULL, NULL); if (err) goto done; errcode = pthread_mutex_lock(&tog_mutex);