commit 1758cce7892c5bec4d4ccd3de91615c3c78b23cb from: Stefan Sperling via: Thomas Adam date: Mon Jun 13 17:55:22 2022 UTC reuse a temporary file across commits during got log -p -S suggested by + ok op@ commit - 6fdca49ec99627a96cda79e00f938049a317e6ef commit + 1758cce7892c5bec4d4ccd3de91615c3c78b23cb blob - 07bc4bd4b8a9a8c6c3de55769ca8f2dbb3d217b6 blob + 28b7c58946126425fb58c0b17940971c270110ba --- got/got.c +++ got/got.c @@ -3775,10 +3775,9 @@ match_changed_paths(int *have_match, struct got_pathli static const struct got_error * match_patch(int *have_match, struct got_commit_object *commit, struct got_object_id *id, const char *path, int diff_context, - struct got_repository *repo, regex_t *regex) + struct got_repository *repo, regex_t *regex, FILE *f) { const struct got_error *err = NULL; - FILE *f; char *line = NULL; size_t linesize = 0; ssize_t linelen; @@ -3786,9 +3785,9 @@ match_patch(int *have_match, struct got_commit_object *have_match = 0; - f = got_opentemp(); - if (f == NULL) - return got_error_from_errno("got_opentemp"); + err = got_opentemp_truncate(f); + if (err) + return err; err = print_patch(commit, id, path, diff_context, repo, f); if (err) @@ -3807,8 +3806,6 @@ match_patch(int *have_match, struct got_commit_object } done: free(line); - if (fclose(f) == EOF && err == NULL) - err = got_error_from_errno("fclose"); return err; } @@ -4015,7 +4012,8 @@ print_commits(struct got_object_id *root_id, struct go struct got_repository *repo, const char *path, int show_changed_paths, int show_patch, const char *search_pattern, int diff_context, int limit, int log_branches, int reverse_display_order, - struct got_reflist_object_id_map *refs_idmap, int one_line) + struct got_reflist_object_id_map *refs_idmap, int one_line, + FILE *tmpfile) { const struct got_error *err; struct got_commit_graph *graph; @@ -4078,7 +4076,8 @@ print_commits(struct got_object_id *root_id, struct go &changed_paths, ®ex); if (have_match == 0 && show_patch) { err = match_patch(&have_match, commit, id, - path, diff_context, repo, ®ex); + path, diff_context, repo, ®ex, + tmpfile); if (err) break; } @@ -4206,6 +4205,7 @@ cmd_log(int argc, char *argv[]) const char *errstr; struct got_reflist_head refs; struct got_reflist_object_id_map *refs_idmap = NULL; + FILE *tmpfile = NULL; TAILQ_INIT(&refs); @@ -4397,9 +4397,18 @@ cmd_log(int argc, char *argv[]) worktree = NULL; } + if (search_pattern && show_patch) { + tmpfile = got_opentemp(); + if (tmpfile == NULL) { + error = got_error_from_errno("got_opentemp"); + goto done; + } + } + error = print_commits(start_id, end_id, repo, path ? path : "", show_changed_paths, show_patch, search_pattern, diff_context, - limit, log_branches, reverse_display_order, refs_idmap, one_line); + limit, log_branches, reverse_display_order, refs_idmap, one_line, + tmpfile); done: free(path); free(repo_path); @@ -4413,6 +4422,8 @@ done: } if (refs_idmap) got_reflist_object_id_map_free(refs_idmap); + if (tmpfile && fclose(tmpfile) == EOF && error == NULL) + error = got_error_from_errno("fclose"); got_ref_list_free(&refs); return error; } blob - 82d4fbdc322a75119d06855ff7c5d7879bcb9648 blob + 5df60c352cb02c68869dfd77742c78669f368df6 --- include/got_opentemp.h +++ include/got_opentemp.h @@ -37,3 +37,6 @@ const struct got_error *got_opentemp_named(char **, FI /* Like got_opentemp_named() but returns a file descriptor instead of a FILE. */ const struct got_error *got_opentemp_named_fd(char **, int *, const char *); + +/* Truncate a file. This is useful for re-using open temporary files. */ +const struct got_error *got_opentemp_truncate(FILE *); blob - e227f8393f7b43a261f819b8bd2909ce18a6cdb4 blob + 420ad693dd5543912fea36afad97a2ff9e02c1ba --- lib/diff.c +++ lib/diff.c @@ -31,6 +31,7 @@ #include "got_path.h" #include "got_cancel.h" #include "got_worktree.h" +#include "got_opentemp.h" #include "got_lib_diff.h" #include "got_lib_delta.h" @@ -52,18 +53,6 @@ add_line_offset(off_t **line_offsets, size_t *nlines, } static const struct got_error * -reset_file(FILE *f) -{ - if (fpurge(f) == EOF) - return got_error_from_errno("fpurge"); - if (ftruncate(fileno(f), 0L) == -1) - return got_error_from_errno("ftruncate"); - if (fseeko(f, 0L, SEEK_SET) == -1) - return got_error_from_errno("fseeko"); - return NULL; -} - -static const struct got_error * diff_blobs(off_t **line_offsets, size_t *nlines, struct got_diffreg_result **resultp, struct got_blob_object *blob1, struct got_blob_object *blob2, FILE *f1, FILE *f2, @@ -91,12 +80,12 @@ diff_blobs(off_t **line_offsets, size_t *nlines, *resultp = NULL; if (f1) { - err = reset_file(f1); + err = got_opentemp_truncate(f1); if (err) goto done; } if (f2) { - err = reset_file(f2); + err = got_opentemp_truncate(f2); if (err) goto done; } blob - 5e6ad4d2aa42f0b97318ff7e1e86b7e8c6ed7055 blob + 26116c3f47dfcdbc7f734406539e46e2cce8a1b4 --- lib/opentemp.c +++ lib/opentemp.c @@ -115,3 +115,15 @@ got_opentemp_named_fd(char **path, int *outfd, const c *outfd = fd; return err; } + +const struct got_error * +got_opentemp_truncate(FILE *f) +{ + if (fpurge(f) == EOF) + return got_error_from_errno("fpurge"); + if (ftruncate(fileno(f), 0L) == -1) + return got_error_from_errno("ftruncate"); + if (fseeko(f, 0L, SEEK_SET) == -1) + return got_error_from_errno("fseeko"); + return NULL; +}