commit - 0dca135e7628142c56b3f71c3b5eb875f4fe6c7f
commit + 4b752015b5208a96c2d1b6c1c6b8589884b8b2b6
blob - d9c4a8353c2a3778cc4d66443ac60c9d35daa07b
blob + 5f7f00007937a048564e685aac0a8c6b9e98adab
--- got/got.c
+++ got/got.c
while (path[0] == '/')
path++;
err = got_diff_blob(NULL, NULL, blob1, blob2, f1, f2, path, path,
- diff_context, ignore_whitespace, force_text_diff, outfile);
+ GOT_DIFF_ALGORITHM_PATIENCE, diff_context, ignore_whitespace,
+ force_text_diff, outfile);
done:
if (fd1 != -1 && close(fd1) == -1 && err == NULL)
err = got_error_from_errno("close");
arg.diff_context = diff_context;
arg.ignore_whitespace = ignore_whitespace;
arg.force_text_diff = force_text_diff;
+ arg.diff_algo = GOT_DIFF_ALGORITHM_PATIENCE;
arg.outfile = outfile;
arg.line_offsets = NULL;
arg.nlines = 0;
const char *id_str;
int header_shown;
int diff_staged;
+ enum got_diff_algorithm diff_algo;
int ignore_whitespace;
int force_text_diff;
FILE *f1;
}
err = got_diff_objects_as_blobs(NULL, NULL, a->f1, a->f2,
fd1, fd2, blob_id, staged_blob_id, label1, label2,
- a->diff_context, a->ignore_whitespace, a->force_text_diff,
- a->repo, stdout);
+ a->diff_algo, a->diff_context, a->ignore_whitespace,
+ a->force_text_diff, a->repo, stdout);
goto done;
}
}
err = got_diff_blob_file(blob1, a->f1, size1, label1, f2 ? f2 : a->f2,
- f2_exists, sb.st_size, path, a->diff_context, a->ignore_whitespace,
- a->force_text_diff, stdout);
+ f2_exists, sb.st_size, path, GOT_DIFF_ALGORITHM_PATIENCE,
+ a->diff_context, a->ignore_whitespace, a->force_text_diff, stdout);
done:
if (fd1 != -1 && close(fd1) == -1 && err == NULL)
err = got_error_from_errno("close");
goto done;
arg.repo = repo;
arg.worktree = worktree;
+ arg.diff_algo = GOT_DIFF_ALGORITHM_PATIENCE;
arg.diff_context = diff_context;
arg.id_str = id_str;
arg.header_shown = 0;
switch (type1 == GOT_OBJ_TYPE_ANY ? type2 : type1) {
case GOT_OBJ_TYPE_BLOB:
error = got_diff_objects_as_blobs(NULL, NULL, f1, f2,
- fd1, fd2, ids[0], ids[1], NULL, NULL, diff_context,
+ fd1, fd2, ids[0], ids[1], NULL, NULL,
+ GOT_DIFF_ALGORITHM_PATIENCE, diff_context,
ignore_whitespace, force_text_diff, repo, stdout);
break;
case GOT_OBJ_TYPE_TREE:
error = got_diff_objects_as_trees(NULL, NULL, f1, f2, fd1, fd2,
- ids[0], ids[1], &paths, "", "", diff_context,
+ ids[0], ids[1], &paths, "", "",
+ GOT_DIFF_ALGORITHM_PATIENCE, diff_context,
ignore_whitespace, force_text_diff, repo, stdout);
break;
case GOT_OBJ_TYPE_COMMIT:
printf("diff %s %s\n", labels[0], labels[1]);
error = got_diff_objects_as_commits(NULL, NULL, f1, f2,
- fd1, fd2, ids[0], ids[1], &paths, diff_context,
+ fd1, fd2, ids[0], ids[1], &paths,
+ GOT_DIFF_ALGORITHM_PATIENCE, diff_context,
ignore_whitespace, force_text_diff, repo, stdout);
break;
default:
goto done;
}
error = got_blame(link_target ? link_target : in_repo_path, commit_id,
- repo, blame_cb, &bca, check_cancelled, NULL, fd2, fd3, f1, f2);
+ repo, GOT_DIFF_ALGORITHM_PATIENCE, blame_cb, &bca,
+ check_cancelled, NULL, fd2, fd3, f1, f2);
done:
free(in_repo_path);
free(link_target);
blob - 80bd351ec9bb5cf498aee6074d91b588a3566650
blob + da9f041cbfef9184c60aa257ec187e714ee04860
--- gotweb/gotweb.c
+++ gotweb/gotweb.c
switch (obj_type) {
case GOT_OBJ_TYPE_BLOB:
error = got_diff_objects_as_blobs(NULL, NULL, f1, f2,
- fd1, fd2, id1, id2, NULL, NULL, 3, 0, 0,
- gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, NULL, GOT_DIFF_ALGORITHM_PATIENCE,
+ 3, 0, 0, gw_trans->repo, f);
break;
case GOT_OBJ_TYPE_TREE:
error = got_diff_objects_as_trees(NULL, NULL, f1, f2,
- fd1, fd2, id1, id2, NULL, "", "", 3, 0, 0,
- gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, "", "",
+ GOT_DIFF_ALGORITHM_PATIENCE, 3, 0, 0, gw_trans->repo, f);
break;
case GOT_OBJ_TYPE_COMMIT:
error = got_diff_objects_as_commits(NULL, NULL, f1, f2,
- fd1, fd2, id1, id2, NULL, 3, 0, 0, gw_trans->repo, f);
+ fd1, fd2, id1, id2, NULL, GOT_DIFF_ALGORITHM_PATIENCE,
+ 3, 0, 0, gw_trans->repo, f);
break;
default:
error = got_error(GOT_ERR_OBJ_TYPE);
goto done;
}
- error = got_blame(in_repo_path, commit_id, gw_trans->repo, gw_blame_cb,
- &bca, NULL, NULL, fd2, fd3, f1, f2);
+ error = got_blame(in_repo_path, commit_id, gw_trans->repo,
+ GOT_DIFF_ALGORITHM_PATIENCE, gw_blame_cb, &bca, NULL, NULL,
+ fd2, fd3, f1, f2);
done:
free(in_repo_path);
free(commit_id);
blob - 5d01c0034c2587d4dffbfd407a94631f1cfe7e7c
blob + 7a5d61c35cf7807ba8f820712005a94d28e118fe
--- include/got_blame.h
+++ include/got_blame.h
* aborted and the callback's error is returned from this function.
*/
const struct got_error *got_blame(const char *,
- struct got_object_id *, struct got_repository *,
+ struct got_object_id *, struct got_repository *, enum got_diff_algorithm,
got_blame_cb, void *, got_cancel_cb, void *, int, int, FILE *, FILE *);
blob - e04cc7fd9e3459de5ae8004badfe6704feaea240
blob + 4243be1c5479449f6d3623e760d1979bd58682b8
--- include/got_diff.h
+++ include/got_diff.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+enum got_diff_algorithm {
+ GOT_DIFF_ALGORITHM_MYERS,
+ GOT_DIFF_ALGORITHM_PATIENCE,
+};
+
/*
* Compute the differences between two blobs and write unified diff text
* to the provided output file. Two open temporary files must be provided
*/
const struct got_error *got_diff_blob(off_t **, size_t *,
struct got_blob_object *, struct got_blob_object *, FILE *, FILE *,
- const char *, const char *, int, int, int, FILE *);
+ const char *, const char *, enum got_diff_algorithm, int, int, int,
+ FILE *);
/*
* Compute the differences between a blob and a file and write unified diff
* Whitespace differences may optionally be ignored.
*/
const struct got_error *got_diff_blob_file(struct got_blob_object *, FILE *,
- off_t, const char *, FILE *, int, size_t, const char *, int, int, int,
- FILE *);
+ off_t, const char *, FILE *, int, size_t, const char *,
+ enum got_diff_algorithm, int, int, int, FILE *);
/*
* A callback function invoked to handle the differences between two blobs
int diff_context; /* Sets the number of context lines. */
int ignore_whitespace; /* Ignore whitespace differences. */
int force_text_diff; /* Assume text even if binary data detected. */
+ enum got_diff_algorithm diff_algo; /* Diffing algorithm to use. */
/*
* The number of lines contained in produced unidiff text output,
*/
const struct got_error *got_diff_objects_as_blobs(off_t **, size_t *,
FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- const char *, const char *, int, int, int,
+ const char *, const char *, enum got_diff_algorithm, int, int, int,
struct got_repository *, FILE *);
+struct got_pathlist_head;
+
/*
* Diff two objects, assuming both objects are trees. Two const char * diff
* header labels may be provided which will be used to identify each blob in
*/
const struct got_error *got_diff_objects_as_trees(off_t **, size_t *,
FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- struct got_pathlist_head *, const char *, const char *, int, int, int,
- struct got_repository *, FILE *);
+ struct got_pathlist_head *, const char *, const char *,
+ enum got_diff_algorithm, int, int, int, struct got_repository *, FILE *);
/*
* Diff two objects, assuming both objects are commits.
*/
const struct got_error *got_diff_objects_as_commits(off_t **, size_t *,
FILE *, FILE *, int, int, struct got_object_id *, struct got_object_id *,
- struct got_pathlist_head *, int, int, int, struct got_repository *, FILE *);
+ struct got_pathlist_head *, enum got_diff_algorithm, int, int, int,
+ struct got_repository *, FILE *);
#define GOT_DIFF_MAX_CONTEXT 64
blob - f08e9f18773211db7d75c2ee3de198ad23a08e01
blob + 05701b819fcf75cc1c3d627b88c1f75ff8597911
--- lib/blame.c
+++ lib/blame.c
#include "got_error.h"
#include "got_object.h"
#include "got_cancel.h"
-#include "got_blame.h"
#include "got_commit_graph.h"
#include "got_opentemp.h"
+#include "got_diff.h"
+#include "got_blame.h"
#include "got_lib_inflate.h"
#include "got_lib_delta.h"
static const struct got_error *
blame_open(struct got_blame **blamep, const char *path,
struct got_object_id *start_commit_id, struct got_repository *repo,
- got_blame_cb cb, void *arg, got_cancel_cb cancel_cb, void *cancel_arg,
+ enum got_diff_algorithm diff_algo, got_blame_cb cb, void *arg,
+ got_cancel_cb cancel_cb, void *cancel_arg,
int fd1, int fd2, FILE *f1, FILE *f2)
{
const struct got_error *err = NULL;
blame->f2 = f2;
blame->fd = fd2;
- err = got_diff_get_config(&blame->cfg, GOT_DIFF_ALGORITHM_PATIENCE,
- blame_atomize_file, blame);
+ err = got_diff_get_config(&blame->cfg, diff_algo, blame_atomize_file,
+ blame);
if (err)
goto done;
const struct got_error *
got_blame(const char *path, struct got_object_id *commit_id,
- struct got_repository *repo, got_blame_cb cb, void *arg,
- got_cancel_cb cancel_cb, void* cancel_arg, int fd1, int fd2, FILE *f1,
- FILE *f2)
+ struct got_repository *repo, enum got_diff_algorithm diff_algo,
+ got_blame_cb cb, void *arg, got_cancel_cb cancel_cb, void* cancel_arg,
+ int fd1, int fd2, FILE *f1, FILE *f2)
{
const struct got_error *err = NULL, *close_err = NULL;
struct got_blame *blame;
if (asprintf(&abspath, "%s%s", path[0] == '/' ? "" : "/", path) == -1)
return got_error_from_errno2("asprintf", path);
- err = blame_open(&blame, abspath, commit_id, repo, cb, arg,
- cancel_cb, cancel_arg, fd1, fd2, f1, f2);
+ err = blame_open(&blame, abspath, commit_id, repo, diff_algo,
+ cb, arg, cancel_cb, cancel_arg, fd1, fd2, f1, f2);
free(abspath);
if (blame)
close_err = blame_close(blame);
blob - 500149f5a3358f499c291ab40acdc5142bf68184
blob + 7268a714345f26eb33869d80941662fdd7688b13
--- lib/diff.c
+++ lib/diff.c
struct got_diffreg_result **resultp, struct got_blob_object *blob1,
struct got_blob_object *blob2, FILE *f1, FILE *f2,
const char *label1, const char *label2, mode_t mode1, mode_t mode2,
- int diff_context, int ignore_whitespace, int force_text_diff, FILE *outfile)
+ int diff_context, int ignore_whitespace, int force_text_diff, FILE *outfile,
+ enum got_diff_algorithm diff_algo)
{
const struct got_error *err = NULL, *free_err;
char hex1[SHA1_DIGEST_STRING_LENGTH];
free(modestr1);
free(modestr2);
}
- err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_PATIENCE,
- ignore_whitespace, force_text_diff);
+ err = got_diffreg(&result, f1, f2, diff_algo, ignore_whitespace,
+ force_text_diff);
if (err)
goto done;
return diff_blobs(&a->line_offsets, &a->nlines, NULL,
blob1, blob2, f1, f2, label1, label2, mode1, mode2, a->diff_context,
- a->ignore_whitespace, a->force_text_diff, a->outfile);
+ a->ignore_whitespace, a->force_text_diff, a->outfile, a->diff_algo);
}
const struct got_error *
got_diff_blob(off_t **line_offsets, size_t *nlines,
struct got_blob_object *blob1, struct got_blob_object *blob2,
FILE *f1, FILE *f2, const char *label1, const char *label2,
- int diff_context, int ignore_whitespace, int force_text_diff,
- FILE *outfile)
+ enum got_diff_algorithm diff_algo, int diff_context,
+ int ignore_whitespace, int force_text_diff, FILE *outfile)
{
return diff_blobs(line_offsets, nlines, NULL, blob1, blob2, f1, f2,
label1, label2, 0, 0, diff_context, ignore_whitespace,
- force_text_diff, outfile);
+ force_text_diff, outfile, diff_algo);
}
static const struct got_error *
diff_blob_file(struct got_diffreg_result **resultp,
struct got_blob_object *blob1, FILE *f1, off_t size1, const char *label1,
- FILE *f2, int f2_exists, size_t size2, const char *label2, int diff_context,
- int ignore_whitespace, int force_text_diff, FILE *outfile)
+ FILE *f2, int f2_exists, size_t size2, const char *label2,
+ enum got_diff_algorithm diff_algo, int diff_context, int ignore_whitespace,
+ int force_text_diff, FILE *outfile)
{
const struct got_error *err = NULL, *free_err;
char hex1[SHA1_DIGEST_STRING_LENGTH];
f2_exists ? label2 : "/dev/null");
}
- err = got_diffreg(&result, f1, f2, GOT_DIFF_ALGORITHM_PATIENCE,
- ignore_whitespace, force_text_diff);
+ err = got_diffreg(&result, f1, f2, diff_algo, ignore_whitespace,
+ force_text_diff);
if (err)
goto done;
const struct got_error *
got_diff_blob_file(struct got_blob_object *blob1, FILE *f1, off_t size1,
const char *label1, FILE *f2, int f2_exists, size_t size2,
- const char *label2, int diff_context, int ignore_whitespace,
- int force_text_diff, FILE *outfile)
+ const char *label2, enum got_diff_algorithm diff_algo, int diff_context,
+ int ignore_whitespace, int force_text_diff, FILE *outfile)
{
return diff_blob_file(NULL, blob1, f1, size1, label1, f2, f2_exists,
- size2, label2, diff_context, ignore_whitespace, force_text_diff,
- outfile);
+ size2, label2, diff_algo, diff_context, ignore_whitespace,
+ force_text_diff, outfile );
}
static const struct got_error *
got_diff_objects_as_blobs(off_t **line_offsets, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
- const char *label1, const char *label2, int diff_context,
+ const char *label1, const char *label2,
+ enum got_diff_algorithm diff_algo, int diff_context,
int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
{
goto done;
}
err = got_diff_blob(line_offsets, nlines, blob1, blob2, f1, f2,
- label1, label2, diff_context, ignore_whitespace, force_text_diff,
- outfile);
+ label1, label2, diff_algo, diff_context, ignore_whitespace,
+ force_text_diff, outfile);
done:
if (blob1)
got_object_blob_close(blob1);
struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
int diff_context, int ignore_whitespace, int force_text_diff,
- struct got_repository *repo, FILE *outfile)
+ struct got_repository *repo, FILE *outfile,
+ enum got_diff_algorithm diff_algo)
{
const struct got_error *err;
struct got_tree_object *tree1 = NULL, *tree2 = NULL;
goto done;
}
+ arg.diff_algo = diff_algo;
arg.diff_context = diff_context;
arg.ignore_whitespace = ignore_whitespace;
arg.force_text_diff = force_text_diff;
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
struct got_pathlist_head *paths, const char *label1, const char *label2,
- int diff_context, int ignore_whitespace, int force_text_diff,
- struct got_repository *repo, FILE *outfile)
+ enum got_diff_algorithm diff_algo, int diff_context, int ignore_whitespace,
+ int force_text_diff, struct got_repository *repo, FILE *outfile)
{
const struct got_error *err;
char *idstr = NULL;
err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
id1, id2, paths, label1, label2, diff_context, ignore_whitespace,
- force_text_diff, repo, outfile);
+ force_text_diff, repo, outfile, diff_algo);
done:
free(idstr);
return err;
got_diff_objects_as_commits(off_t **line_offsets, size_t *nlines,
FILE *f1, FILE *f2, int fd1, int fd2,
struct got_object_id *id1, struct got_object_id *id2,
- struct got_pathlist_head *paths,
+ struct got_pathlist_head *paths, enum got_diff_algorithm diff_algo,
int diff_context, int ignore_whitespace, int force_text_diff,
struct got_repository *repo, FILE *outfile)
{
err = diff_objects_as_trees(line_offsets, nlines, f1, f2, fd1, fd2,
commit1 ? got_object_commit_get_tree_id(commit1) : NULL,
got_object_commit_get_tree_id(commit2), paths, "", "",
- diff_context, ignore_whitespace, force_text_diff, repo, outfile);
+ diff_context, ignore_whitespace, force_text_diff, repo, outfile,
+ diff_algo);
done:
if (commit1)
got_object_commit_close(commit1);
got_diff_files(struct got_diffreg_result **resultp,
FILE *f1, int f1_exists, const char *label1, FILE *f2, int f2_exists,
const char *label2, int diff_context, int ignore_whitespace,
- int force_text_diff, FILE *outfile)
+ int force_text_diff, FILE *outfile, enum got_diff_algorithm diff_algo)
{
const struct got_error *err = NULL;
struct got_diffreg_result *diffreg_result = NULL;
f2_exists ? label2 : "/dev/null");
}
- err = got_diffreg(&diffreg_result, f1, f2, GOT_DIFF_ALGORITHM_PATIENCE,
+ err = got_diffreg(&diffreg_result, f1, f2, diff_algo,
ignore_whitespace, force_text_diff);
if (err)
goto done;
blob - f28b50b2a51b0e0f388b22fcf87b63f52408a2e1
blob + 3acd317409597e7f1fcd02cd18e0db989737c6f4
--- lib/diff3.c
+++ lib/diff3.c
#include "got_error.h"
#include "got_opentemp.h"
#include "got_object.h"
+#include "got_diff.h"
#include "buf.h"
#include "rcsutil.h"
blob - 186401edf2e3a5402baefc29f867ea4fcbf0b2db
blob + 30c7388ad74a1c5e2b958cf79a9f5c1790de245d
--- lib/diffreg.c
+++ lib/diffreg.c
#include "got_object.h"
#include "got_opentemp.h"
#include "got_error.h"
+#include "got_diff.h"
#include "got_lib_diff.h"
blob - 0157c869fff0c97a45ce1c6fc4f72dcca8c9f2b6
blob + 3ff8d96891722f9a89a5245a2fb9b5e5c8424e83
--- lib/got_lib_diff.h
+++ lib/got_lib_diff.h
#include "diff_main.h"
#include "diff_output.h"
-enum got_diff_algorithm {
- GOT_DIFF_ALGORITHM_MYERS,
- GOT_DIFF_ALGORITHM_PATIENCE,
-};
-
enum got_diff_output_format {
GOT_DIFF_OUTPUT_UNIDIFF,
GOT_DIFF_OUTPUT_EDSCRIPT,
const char *, const char *, const char *, enum got_diff_algorithm);
const struct got_error *got_diff_files(struct got_diffreg_result **, FILE *,
- int, const char *, FILE *, int, const char *, int, int, int, FILE *);
+ int, const char *, FILE *, int, const char *, int, int, int, FILE *,
+ enum got_diff_algorithm);
blob - 0d8af2c12bd05d1cd95f0b8226a4e9a708ea99a0
blob + 6b6915f9998d30a1ae5b1846365b299ba2c974fe
--- lib/patch.c
+++ lib/patch.c
#include "got_repository.h"
#include "got_opentemp.h"
#include "got_patch.h"
+#include "got_diff.h"
#include "got_lib_delta.h"
#include "got_lib_diff.h"
blob - c6a2aa553557aa15a464291525d9d8c0ee48bcb8
blob + 585486aa9bd3b5620681a9e4ccad89befbbaf36b
--- lib/worktree.c
+++ lib/worktree.c
goto done;
err = got_diff_files(&diffreg_result, f1, 1, id_str, f2, 1, path2,
- 3, 0, 1, NULL);
+ 3, 0, 1, NULL, GOT_DIFF_ALGORITHM_MYERS);
if (err)
goto done;
goto done;
err = got_diff_files(&diffreg_result, f1, 1, label1, f2, 1,
- path2, 3, 0, 1, NULL);
+ path2, 3, 0, 1, NULL, GOT_DIFF_ALGORITHM_MYERS);
if (err)
goto done;
blob - e7cd627fd82955639423a579cf6346f539437542
blob + 800384dacf0faed4893832dd2760af45e28cb8c7
--- tog/tog.c
+++ tog/tog.c
int first_displayed_line;
int last_displayed_line;
int eof;
+ enum got_diff_algorithm diff_algo;
int diff_context;
int ignore_whitespace;
int force_text_diff;
case GOT_OBJ_TYPE_BLOB:
err = got_diff_objects_as_blobs(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2,
- s->label1, s->label2, s->diff_context,
+ s->label1, s->label2, s->diff_algo, s->diff_context,
s->ignore_whitespace, s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_TREE:
err = got_diff_objects_as_trees(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL, "", "",
- s->diff_context, s->ignore_whitespace, s->force_text_diff,
- s->repo, s->f);
+ s->diff_algo, s->diff_context, s->ignore_whitespace,
+ s->force_text_diff, s->repo, s->f);
break;
case GOT_OBJ_TYPE_COMMIT: {
const struct got_object_id_queue *parent_ids;
err = got_diff_objects_as_commits(&s->line_offsets, &s->nlines,
s->f1, s->f2, s->fd1, s->fd2, s->id1, s->id2, NULL,
- s->diff_context, s->ignore_whitespace, s->force_text_diff,
- s->repo, s->f);
+ s->diff_algo, s->diff_context, s->ignore_whitespace,
+ s->force_text_diff, s->repo, s->f);
break;
}
default:
s->first_displayed_line = 1;
s->last_displayed_line = view->nlines;
+ s->diff_algo = GOT_DIFF_ALGORITHM_MYERS;
s->diff_context = diff_context;
s->ignore_whitespace = ignore_whitespace;
s->force_text_diff = force_text_diff;
goto done;
err = got_blame(ta->path, a->commit_id, ta->repo,
- blame_cb, ta->cb_args, ta->cancel_cb, ta->cancel_arg, fd1, fd2, f1,
- f2);
+ GOT_DIFF_ALGORITHM_MYERS, blame_cb, ta->cb_args,
+ ta->cancel_cb, ta->cancel_arg, fd1, fd2, f1, f2);
if (err && err->code == GOT_ERR_CANCELLED)
err = NULL;