commit d68a0a7de13af722c55099582019c03240e13320 from: Stefan Sperling date: Tue Jul 10 11:47:25 2018 UTC implement cleaner cancellation of tog's blame view commit - 75b7a700d9d14ef8eb902961255212acbedef164 commit + d68a0a7de13af722c55099582019c03240e13320 blob - c787aadf05e2afab61bd34976f7349912252e6da blob + 5255d076c915accf159940978b821d06803ff2f8 --- include/got_blame.h +++ include/got_blame.h @@ -28,6 +28,15 @@ const struct got_error *got_blame(const char *, struct * The callback receives the provided void * argument, the total number * of lines of the annotated file, a line number, and the ID of the commit * which last changed this line. + * + * The callback is invoked for each commit as history is traversed. + * If no changes to the file were made in a commit, line number -1 and + * commit ID NULL will be reported. + * + * If the callback returns GOT_ERR_ITER_COMPLETED, the blame operation + * will be aborted and this function returns NULL. + * If the callback returns any other error, the blame operation will be + * aborted and the callback's error is returned from this function. */ const struct got_error *got_blame_incremental(const char *, struct got_object_id *, struct got_repository *, blob - c57eaabaef3b116c178390d76ee554ebbb2e16e9 blob + a6ac4fec63e6c9041d7c5cc75a0c8df7a3cf86d2 --- lib/blame.c +++ lib/blame.c @@ -132,7 +132,8 @@ blame_commit(struct got_blame *blame, struct got_objec goto done; } } - } + } else if (cb) + err = cb(arg, blame->nlines, -1, NULL); done: if (obj) got_object_close(obj); blob - 581999675170afab7819c5cb96bad859a29b2545 blob + 400eda3f35aa381e3cfb172ace64f7974e8ed066 --- tog/tog.c +++ tog/tog.c @@ -1135,17 +1135,26 @@ blame_cb(void *arg, int nlines, int lineno, struct got struct tog_blame_cb_args *a = arg; struct tog_blame_line *line; int eof; - - if (*a->done) - return got_error(GOT_ERR_ITER_COMPLETED); - if (nlines != a->nlines || lineno < 1 || lineno > a->nlines) + if (nlines != a->nlines || + (lineno != -1 && lineno < 1) || lineno > a->nlines) return got_error(GOT_ERR_RANGE); if (pthread_mutex_lock(a->mutex) != 0) return got_error_from_errno(); + if (*a->done) { /* user has quit the blame view */ + err = got_error(GOT_ERR_ITER_COMPLETED); + goto done; + } + + if (lineno == -1) + goto done; /* no change in this commit */ + line = &a->lines[lineno - 1]; + if (line->annotated) + goto done; + line->id = got_object_id_dup(id); if (line->id == NULL) { err = got_error_from_errno();