diff options
| author | Junio C Hamano <gitster@pobox.com> | 2022-06-07 14:10:56 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2022-06-07 14:10:56 -0700 |
| commit | 2da81d1efb0166e1cec7a8582b837994dde6225b (patch) | |
| tree | 43763a6b702eb4244724f3c7bedd3537f1f4406a /builtin | |
| parent | f31b624495077ab7b173b41f28cea52db874aa6b (diff) | |
| parent | 54c8a7c379fc37a847b8a5ec5c419eae171322e1 (diff) | |
| download | git-2da81d1efb0166e1cec7a8582b837994dde6225b.tar.gz | |
Merge branch 'ab/plug-leak-in-revisions'
Plug the memory leaks from the trickiest API of all, the revision
walker.
* ab/plug-leak-in-revisions: (27 commits)
revisions API: add a TODO for diff_free(&revs->diffopt)
revisions API: have release_revisions() release "topo_walk_info"
revisions API: have release_revisions() release "date_mode"
revisions API: call diff_free(&revs->pruning) in revisions_release()
revisions API: release "reflog_info" in release revisions()
revisions API: clear "boundary_commits" in release_revisions()
revisions API: have release_revisions() release "prune_data"
revisions API: have release_revisions() release "grep_filter"
revisions API: have release_revisions() release "filter"
revisions API: have release_revisions() release "cmdline"
revisions API: have release_revisions() release "mailmap"
revisions API: have release_revisions() release "commits"
revisions API users: use release_revisions() for "prune_data" users
revisions API users: use release_revisions() with UNLEAK()
revisions API users: use release_revisions() in builtin/log.c
revisions API users: use release_revisions() in http-push.c
revisions API users: add "goto cleanup" for release_revisions()
stash: always have the owner of "stash_info" free it
revisions API users: use release_revisions() needing REV_INFO_INIT
revision.[ch]: document and move code declared around "init"
...
Diffstat (limited to 'builtin')
| -rw-r--r-- | builtin/add.c | 3 | ||||
| -rw-r--r-- | builtin/am.c | 3 | ||||
| -rw-r--r-- | builtin/bisect--helper.c | 2 | ||||
| -rw-r--r-- | builtin/blame.c | 4 | ||||
| -rw-r--r-- | builtin/checkout.c | 3 | ||||
| -rw-r--r-- | builtin/commit.c | 6 | ||||
| -rw-r--r-- | builtin/describe.c | 2 | ||||
| -rw-r--r-- | builtin/diff-files.c | 8 | ||||
| -rw-r--r-- | builtin/diff-index.c | 5 | ||||
| -rw-r--r-- | builtin/diff.c | 2 | ||||
| -rw-r--r-- | builtin/fast-export.c | 1 | ||||
| -rw-r--r-- | builtin/log.c | 36 | ||||
| -rw-r--r-- | builtin/merge.c | 2 | ||||
| -rw-r--r-- | builtin/pack-objects.c | 2 | ||||
| -rw-r--r-- | builtin/prune.c | 1 | ||||
| -rw-r--r-- | builtin/reflog.c | 1 | ||||
| -rw-r--r-- | builtin/rev-list.c | 25 | ||||
| -rw-r--r-- | builtin/shortlog.c | 8 | ||||
| -rw-r--r-- | builtin/stash.c | 115 | ||||
| -rw-r--r-- | builtin/submodule--helper.c | 14 |
20 files changed, 150 insertions, 93 deletions
diff --git a/builtin/add.c b/builtin/add.c index 145fc9b8f2..f84372964c 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -151,7 +151,7 @@ int add_files_to_cache(const char *prefix, run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); end_odb_transaction(); - clear_pathspec(&rev.prune_data); + release_revisions(&rev); return !!data.add_errors; } @@ -344,6 +344,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix) unlink(file); free(file); + release_revisions(&rev); return 0; } diff --git a/builtin/am.c b/builtin/am.c index 0f4111bafa..93bec62afa 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1397,6 +1397,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm add_pending_object(&rev_info, &commit->object, ""); diff_setup_done(&rev_info.diffopt); log_tree_commit(&rev_info, commit); + release_revisions(&rev_info); } /** @@ -1429,6 +1430,7 @@ static void write_index_patch(const struct am_state *state) add_pending_object(&rev_info, &tree->object, ""); diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, 1); + release_revisions(&rev_info); } /** @@ -1582,6 +1584,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa add_pending_oid(&rev_info, "HEAD", &our_tree, 0); diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, 1); + release_revisions(&rev_info); } if (run_apply(state, index_path)) diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index d4eaaa345e..8a052c7111 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -596,6 +596,7 @@ static int bisect_skipped_commits(struct bisect_terms *terms) reset_revision_walk(); strbuf_release(&commit_name); + release_revisions(&revs); fclose(fp); return 0; } @@ -1084,6 +1085,7 @@ static enum bisect_error bisect_skip(struct bisect_terms *terms, const char **ar oid_to_hex(&commit->object.oid)); reset_revision_walk(); + release_revisions(&revs); } else { strvec_push(&argv_state, argv[i]); } diff --git a/builtin/blame.c b/builtin/blame.c index e33372c56b..02e39420b6 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1171,7 +1171,7 @@ parse_done: if (!incremental) setup_pager(); else - return 0; + goto cleanup; blame_sort_final(&sb); @@ -1205,6 +1205,8 @@ parse_done: printf("num commits: %d\n", sb.num_commits); } +cleanup: cleanup_scoreboard(&sb); + release_revisions(&revs); return 0; } diff --git a/builtin/checkout.c b/builtin/checkout.c index f988936ddf..2eefda81d8 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -629,7 +629,7 @@ static void show_local_changes(struct object *head, diff_setup_done(&rev.diffopt); add_pending_object(&rev, head, NULL); run_diff_index(&rev, 0); - object_array_clear(&rev.pending); + release_revisions(&rev); } static void describe_detached_head(const char *msg, struct commit *commit) @@ -1082,6 +1082,7 @@ static void orphaned_commit_warning(struct commit *old_commit, struct commit *ne /* Clean up objects used, as they will be reused. */ repo_clear_commit_marks(the_repository, ALL_REV_FLAGS); + release_revisions(&revs); } static int switch_branches(const struct checkout_opts *opts, diff --git a/builtin/commit.c b/builtin/commit.c index 9bbc7f8075..fcf9c85947 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1100,7 +1100,6 @@ static const char *find_author_by_nickname(const char *name) struct rev_info revs; struct commit *commit; struct strbuf buf = STRBUF_INIT; - struct string_list mailmap = STRING_LIST_INIT_NODUP; const char *av[20]; int ac = 0; @@ -1111,7 +1110,8 @@ static const char *find_author_by_nickname(const char *name) av[++ac] = buf.buf; av[++ac] = NULL; setup_revisions(ac, av, &revs, NULL); - revs.mailmap = &mailmap; + revs.mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(revs.mailmap); read_mailmap(revs.mailmap); if (prepare_revision_walk(&revs)) @@ -1122,7 +1122,7 @@ static const char *find_author_by_nickname(const char *name) ctx.date_mode.type = DATE_NORMAL; strbuf_release(&buf); format_commit_message(commit, "%aN <%aE>", &buf, &ctx); - clear_mailmap(&mailmap); + release_revisions(&revs); return strbuf_detach(&buf, NULL); } die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name); diff --git a/builtin/describe.c b/builtin/describe.c index 42159cd26b..a76f1a1a7a 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -517,6 +517,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst) traverse_commit_list(&revs, process_commit, process_object, &pcd); reset_revision_walk(); + release_revisions(&revs); } static void describe(const char *arg, int last_one) @@ -667,6 +668,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) suffix = NULL; else suffix = dirty; + release_revisions(&revs); } describe("HEAD", 1); } else if (dirty) { diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 70103c4095..2bfaf9ba7a 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -77,8 +77,12 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); - return -1; + result = -1; + goto cleanup; } +cleanup: result = run_diff_files(&rev, options); - return diff_result_code(&rev.diffopt, result); + result = diff_result_code(&rev.diffopt, result); + release_revisions(&rev); + return result; } diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 5fd23ab5b6..7d158af6b6 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -70,6 +70,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) return -1; } result = run_diff_index(&rev, option); - UNLEAK(rev); - return diff_result_code(&rev.diffopt, result); + result = diff_result_code(&rev.diffopt, result); + release_revisions(&rev); + return result; } diff --git a/builtin/diff.c b/builtin/diff.c index 3397f44d5a..54bb3de964 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -594,7 +594,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) result = diff_result_code(&rev.diffopt, result); if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); - UNLEAK(rev); + release_revisions(&rev); UNLEAK(ent); UNLEAK(blob); return result; diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 1355b5a96d..e1748fb98b 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -1276,6 +1276,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) printf("done\n"); refspec_clear(&refspecs); + release_revisions(&revs); return 0; } diff --git a/builtin/log.c b/builtin/log.c index 2eb0063cc1..88a5e98875 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -231,7 +231,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, } if (mailmap) { - rev->mailmap = xcalloc(1, sizeof(struct string_list)); + rev->mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(rev->mailmap); read_mailmap(rev->mailmap); } @@ -294,6 +295,12 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, cmd_log_init_finish(argc, argv, prefix, rev, opt); } +static int cmd_log_deinit(int ret, struct rev_info *rev) +{ + release_revisions(rev); + return ret; +} + /* * This gives a rough estimate for how many commits we * will print out in the list. @@ -565,7 +572,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) cmd_log_init(argc, argv, prefix, &rev, &opt); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } static void show_tagger(const char *buf, struct rev_info *rev) @@ -689,7 +696,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) cmd_log_init(argc, argv, prefix, &rev, &opt); if (!rev.no_walk) - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); count = rev.pending.nr; objects = rev.pending.objects; @@ -749,8 +756,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.diffopt.no_free = 0; diff_free(&rev.diffopt); - free(objects); - return ret; + return cmd_log_deinit(ret, &rev); } /* @@ -778,7 +784,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) rev.always_show_header = 1; cmd_log_init_finish(argc, argv, prefix, &rev, &opt); - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } static void log_setup_revisions_tweak(struct rev_info *rev, @@ -809,7 +815,7 @@ int cmd_log(int argc, const char **argv, const char *prefix) opt.revarg_opt = REVARG_COMMITTISH; opt.tweak = log_setup_revisions_tweak; cmd_log_init(argc, argv, prefix, &rev, &opt); - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } /* format-patch */ @@ -1764,6 +1770,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) struct commit *commit; struct commit **list = NULL; struct rev_info rev; + char *to_free = NULL; struct setup_revision_opt s_r_opt; int nr = 0, total, i; int use_stdout = 0; @@ -1965,7 +1972,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) strbuf_addch(&buf, '\n'); } - rev.extra_headers = strbuf_detach(&buf, NULL); + rev.extra_headers = to_free = strbuf_detach(&buf, NULL); if (from) { if (split_ident_line(&rev.from_ident, from, strlen(from))) @@ -2186,8 +2193,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) prepare_bases(&bases, base, list, nr); } - if (in_reply_to || thread || cover_letter) - rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); + if (in_reply_to || thread || cover_letter) { + rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids)); + string_list_init_nodup(rev.ref_message_ids); + } if (in_reply_to) { const char *msgid = clean_message_id(in_reply_to); string_list_append(rev.ref_message_ids, msgid); @@ -2294,8 +2303,11 @@ done: strbuf_release(&rdiff1); strbuf_release(&rdiff2); strbuf_release(&rdiff_title); - UNLEAK(rev); - return 0; + free(to_free); + if (rev.ref_message_ids) + string_list_clear(rev.ref_message_ids, 0); + free(rev.ref_message_ids); + return cmd_log_deinit(0, &rev); } static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) diff --git a/builtin/merge.c b/builtin/merge.c index f178f5a3ee..d9784d4891 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -443,6 +443,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead } write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len); strbuf_release(&out); + release_revisions(&rev); } static void finish(struct commit *head_commit, @@ -998,6 +999,7 @@ static int evaluate_result(void) */ cnt += count_unmerged_entries(); + release_revisions(&rev); return cnt; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 040cebafd2..cc5f41086d 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -4464,11 +4464,13 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) read_object_list_from_stdin(); } else if (pfd.have_revs) { get_object_list(&pfd.revs, rp.nr, rp.v); + release_revisions(&pfd.revs); } else { struct rev_info revs; repo_init_revisions(the_repository, &revs, NULL); get_object_list(&revs, rp.nr, rp.v); + release_revisions(&revs); } cleanup_preferred_base(); if (include_tag && nr_result) diff --git a/builtin/prune.c b/builtin/prune.c index c2bcdc07db..df376b2ed1 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -196,5 +196,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix) prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0); } + release_revisions(&revs); return 0; } diff --git a/builtin/reflog.c b/builtin/reflog.c index c943c2aabe..4dd297dce8 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -293,6 +293,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) if (verbose) printf(_("Marking reachable objects...")); mark_reachable_objects(&revs, 0, 0, NULL); + release_revisions(&revs); if (verbose) putchar('\n'); } diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 572da1472e..30fd8e83ea 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -213,10 +213,8 @@ static void show_commit(struct commit *commit, void *data) static void finish_commit(struct commit *commit) { - if (commit->parents) { - free_commit_list(commit->parents); - commit->parents = NULL; - } + free_commit_list(commit->parents); + commit->parents = NULL; free_commit_buffer(the_repository->parsed_objects, commit); } @@ -502,6 +500,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) int use_bitmap_index = 0; int filter_provided_objects = 0; const char *show_progress = NULL; + int ret = 0; if (argc == 2 && !strcmp(argv[1], "-h")) usage(rev_list_usage); @@ -585,7 +584,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) } if (!strcmp(arg, "--test-bitmap")) { test_bitmap_walk(&revs); - return 0; + goto cleanup; } if (skip_prefix(arg, "--progress=", &arg)) { show_progress = arg; @@ -674,11 +673,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (use_bitmap_index) { if (!try_bitmap_count(&revs, filter_provided_objects)) - return 0; + goto cleanup; if (!try_bitmap_disk_usage(&revs, filter_provided_objects)) - return 0; + goto cleanup; if (!try_bitmap_traversal(&revs, filter_provided_objects)) - return 0; + goto cleanup; } if (prepare_revision_walk(&revs)) @@ -698,8 +697,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) find_bisection(&revs.commits, &reaches, &all, bisect_flags); - if (bisect_show_vars) - return show_bisect_vars(&info, reaches, all); + if (bisect_show_vars) { + ret = show_bisect_vars(&info, reaches, all); + goto cleanup; + } } if (filter_provided_objects) { @@ -754,5 +755,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (show_disk_usage) printf("%"PRIuMAX"\n", (uintmax_t)total_disk_usage); - return 0; +cleanup: + release_revisions(&revs); + return ret; } diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 62c4a4eaba..35825f075e 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -81,8 +81,10 @@ static void insert_one_record(struct shortlog *log, format_subject(&subject, oneline, " "); buffer = strbuf_detach(&subject, NULL); - if (!item->util) - item->util = xcalloc(1, sizeof(struct string_list)); + if (!item->util) { + item->util = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(item->util); + } string_list_append(item->util, buffer); } } @@ -420,6 +422,8 @@ parse_done: else get_from_rev(&rev, &log); + release_revisions(&rev); + shortlog_output(&log); if (log.file != stdout) fclose(log.file); diff --git a/builtin/stash.c b/builtin/stash.c index 3fe549f7d3..68b28f2375 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -117,6 +117,10 @@ struct stash_info { int has_u; }; +#define STASH_INFO_INIT { \ + .revision = STRBUF_INIT, \ +} + static void free_stash_info(struct stash_info *info) { strbuf_release(&info->revision); @@ -158,10 +162,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) if (argc == 1) commit = argv[0]; - strbuf_init(&info->revision, 0); if (!commit) { if (!ref_exists(ref_stash)) { - free_stash_info(info); fprintf_ln(stderr, _("No stash entries found.")); return -1; } @@ -175,11 +177,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) revision = info->revision.buf; - if (get_oid(revision, &info->w_commit)) { - error(_("%s is not a valid reference"), revision); - free_stash_info(info); - return -1; - } + if (get_oid(revision, &info->w_commit)) + return error(_("%s is not a valid reference"), revision); assert_stash_like(info, revision); @@ -198,7 +197,7 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) info->is_stash_ref = !strcmp(expanded_ref, ref_stash); break; default: /* Invalid or ambiguous */ - free_stash_info(info); + break; } free(expanded_ref); @@ -616,10 +615,10 @@ restore_untracked: static int apply_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int quiet = 0; int index = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "index", &index, @@ -631,9 +630,10 @@ static int apply_stash(int argc, const char **argv, const char *prefix) git_stash_apply_usage, 0); if (get_stash_info(&info, argc, argv)) - return -1; + goto cleanup; ret = do_apply_stash(prefix, &info, index, quiet); +cleanup: free_stash_info(&info); return ret; } @@ -669,20 +669,25 @@ static int do_drop_stash(struct stash_info *info, int quiet) return 0; } -static void assert_stash_ref(struct stash_info *info) +static int get_stash_info_assert(struct stash_info *info, int argc, + const char **argv) { - if (!info->is_stash_ref) { - error(_("'%s' is not a stash reference"), info->revision.buf); - free_stash_info(info); - exit(1); - } + int ret = get_stash_info(info, argc, argv); + + if (ret < 0) + return ret; + + if (!info->is_stash_ref) + return error(_("'%s' is not a stash reference"), info->revision.buf); + + return 0; } static int drop_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int quiet = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_END() @@ -691,22 +696,21 @@ static int drop_stash(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_stash_drop_usage, 0); - if (get_stash_info(&info, argc, argv)) - return -1; - - assert_stash_ref(&info); + if (get_stash_info_assert(&info, argc, argv)) + goto cleanup; ret = do_drop_stash(&info, quiet); +cleanup: free_stash_info(&info); return ret; } static int pop_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int index = 0; int quiet = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "index", &index, @@ -717,25 +721,25 @@ static int pop_stash(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_stash_pop_usage, 0); - if (get_stash_info(&info, argc, argv)) - return -1; + if (get_stash_info_assert(&info, argc, argv)) + goto cleanup; - assert_stash_ref(&info); if ((ret = do_apply_stash(prefix, &info, index, quiet))) printf_ln(_("The stash entry is kept in case " "you need it again.")); else ret = do_drop_stash(&info, quiet); +cleanup: free_stash_info(&info); return ret; } static int branch_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; const char *branch = NULL; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct child_process cp = CHILD_PROCESS_INIT; struct option options[] = { OPT_END() @@ -752,7 +756,7 @@ static int branch_stash(int argc, const char **argv, const char *prefix) branch = argv[0]; if (get_stash_info(&info, argc - 1, argv + 1)) - return -1; + goto cleanup; cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-b", NULL); @@ -764,8 +768,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix) if (!ret && info.is_stash_ref) ret = do_drop_stash(&info, 0); +cleanup: free_stash_info(&info); - return ret; } @@ -843,8 +847,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op static int show_stash(int argc, const char **argv, const char *prefix) { int i; - int ret = 0; - struct stash_info info; + int ret = -1; + struct stash_info info = STASH_INFO_INIT; struct rev_info rev; struct strvec stash_args = STRVEC_INIT; struct strvec revision_args = STRVEC_INIT; @@ -862,6 +866,7 @@ static int show_stash(int argc, const char **argv, const char *prefix) UNTRACKED_ONLY, PARSE_OPT_NONEG), OPT_END() }; + int do_usage = 0; init_diff_ui_defaults(); git_config(git_diff_ui_config, NULL); @@ -879,10 +884,8 @@ static int show_stash(int argc, const char **argv, const char *prefix) strvec_push(&revision_args, argv[i]); } - ret = get_stash_info(&info, stash_args.nr, stash_args.v); - strvec_clear(&stash_args); - if (ret) - return -1; + if (get_stash_info(&info, stash_args.nr, stash_args.v)) + goto cleanup; /* * The config settings are applied only if there are not passed @@ -896,16 +899,14 @@ static int show_stash(int argc, const char **argv, const char *prefix) rev.diffopt.output_format |= DIFF_FORMAT_PATCH; if (!show_stat && !show_patch) { - free_stash_info(&info); - return 0; + ret = 0; + goto cleanup; } } argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL); - if (argc > 1) { - free_stash_info(&info); - usage_with_options(git_stash_show_usage, options); - } + if (argc > 1) + goto usage; if (!rev.diffopt.output_format) { rev.diffopt.output_format = DIFF_FORMAT_PATCH; diff_setup_done(&rev.diffopt); @@ -930,8 +931,17 @@ static int show_stash(int argc, const char **argv, const char *prefix) } log_tree_diff_flush(&rev); + ret = diff_result_code(&rev.diffopt, 0); +cleanup: + strvec_clear(&stash_args); free_stash_info(&info); - return diff_result_code(&rev.diffopt, 0); + release_revisions(&rev); + if (do_usage) + usage_with_options(git_stash_show_usage, options); + return ret; +usage: + do_usage = 1; + goto cleanup; } static int do_store_stash(const struct object_id *w_commit, const char *stash_msg, @@ -1065,7 +1075,6 @@ static int check_changes_tracked_files(const struct pathspec *ps) goto done; } - object_array_clear(&rev.pending); result = run_diff_files(&rev, 0); if (diff_result_code(&rev.diffopt, result)) { ret = 1; @@ -1073,7 +1082,7 @@ static int check_changes_tracked_files(const struct pathspec *ps) } done: - clear_pathspec(&rev.prune_data); + release_revisions(&rev); return ret; } @@ -1284,9 +1293,7 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps done: discard_index(&istate); - UNLEAK(rev); - object_array_clear(&rev.pending); - clear_pathspec(&rev.prune_data); + release_revisions(&rev); strbuf_release(&diff_output); remove_path(stash_index_path.buf); return ret; @@ -1428,9 +1435,9 @@ done: static int create_stash(int argc, const char **argv, const char *prefix) { - int ret = 0; + int ret; struct strbuf stash_msg_buf = STRBUF_INIT; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct pathspec ps; /* Starting with argv[1], since argv[0] is "create" */ @@ -1445,6 +1452,7 @@ static int create_stash(int argc, const char **argv, const char *prefix) if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); + free_stash_info(&info); strbuf_release(&stash_msg_buf); return ret; } @@ -1453,7 +1461,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q int keep_index, int patch_mode, int include_untracked, int only_staged) { int ret = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct strbuf patch = STRBUF_INIT; struct strbuf stash_msg_buf = STRBUF_INIT; struct strbuf untracked_files = STRBUF_INIT; @@ -1652,6 +1660,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } done: + free_stash_info(&info); strbuf_release(&stash_msg_buf); return ret; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 12ecadd712..c6c2ba1b6d 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -649,7 +649,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, { char *displaypath; struct strvec diff_files_args = STRVEC_INIT; - struct rev_info rev; + struct rev_info rev = REV_INFO_INIT; int diff_files_result; struct strbuf buf = STRBUF_INIT; const char *git_dir; @@ -736,6 +736,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, cleanup: strvec_clear(&diff_files_args); free(displaypath); + release_revisions(&rev); } static void status_submodule_cb(const struct cache_entry *list_item, @@ -1114,6 +1115,7 @@ static int compute_summary_module_list(struct object_id *head_oid, struct strvec diff_args = STRVEC_INIT; struct rev_info rev; struct module_cb_list list = MODULE_CB_LIST_INIT; + int ret = 0; strvec_push(&diff_args, get_diff_cmd(diff_cmd)); if (info->cached) @@ -1139,11 +1141,13 @@ static int compute_summary_module_list(struct object_id *head_oid, setup_work_tree(); if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); - return -1; + ret = -1; + goto cleanup; } } else if (read_cache() < 0) { perror("read_cache"); - return -1; + ret = -1; + goto cleanup; } if (diff_cmd == DIFF_INDEX) @@ -1151,8 +1155,10 @@ static int compute_summary_module_list(struct object_id *head_oid, else run_diff_files(&rev, 0); prepare_submodule_summary(info, &list); +cleanup: strvec_clear(&diff_args); - return 0; + release_revisions(&rev); + return ret; } static int module_summary(int argc, const char **argv, const char *prefix) |
