commit 6ebb22635171b6f1ad080fe10bf7b13133312957 from: Stefan Sperling via: Thomas Adam date: Wed Jul 26 19:15:43 2023 UTC add cancellation support to the mixed-commits checker in worktree.c commit - 8642913bb1bf2956d44d201e77b88c2b67b7c44d commit + 6ebb22635171b6f1ad080fe10bf7b13133312957 blob - 39d94b689a7e9421e20d46f7f02e9b4e9fede796 blob + 9cf849d5bcd773f1443a12efa6474be19cec79aa --- got/got.c +++ got/got.c @@ -6805,7 +6805,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 - 6fa1241b8f765c16f2781e8b851c292d1f55a064 blob + f030f406e8a794cac4ca4f732883444b6383330e --- lib/worktree.c +++ lib/worktree.c @@ -3233,15 +3233,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); @@ -3250,13 +3263,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); @@ -3273,13 +3288,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) { @@ -3477,6 +3496,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) @@ -3486,8 +3506,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; @@ -8404,11 +8428,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 - 1f00b73ac81c1759f6989da29284af790fed4b74 blob + d40b3fadc427a43f99fe7a1e1b4790786b6b1253 --- tog/tog.c +++ tog/tog.c @@ -3377,7 +3377,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);