aboutsummaryrefslogtreecommitdiffstats
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2024-07-08 14:53:10 -0700
committerJunio C Hamano <gitster@pobox.com>2024-07-08 14:53:10 -0700
commit3997614c249b4b475d07c00556446d8b698d1a49 (patch)
treefc0d71d047b303ec2b25fd0711069e9ba4751dd9 /builtin
parentecf7fc600a5218c9ee3863ee70d5a6e312164f30 (diff)
parentfbf7a46d881429ef5495af7bbf3a6c3dacbf80b3 (diff)
downloadgit-3997614c249b4b475d07c00556446d8b698d1a49.tar.gz
Merge branch 'ps/leakfixes-more'
More memory leaks have been plugged. * ps/leakfixes-more: (29 commits) builtin/blame: fix leaking ignore revs files builtin/blame: fix leaking prefixed paths blame: fix leaking data for blame scoreboards line-range: plug leaking find functions merge: fix leaking merge bases builtin/merge: fix leaking `struct cmdnames` in `get_strategy()` sequencer: fix memory leaks in `make_script_with_merges()` builtin/clone: plug leaking HEAD ref in `wanted_peer_refs()` apply: fix leaking string in `match_fragment()` sequencer: fix leaking string buffer in `commit_staged_changes()` commit: fix leaking parents when calling `commit_tree_extended()` config: fix leaking "core.notesref" variable rerere: fix various trivial leaks builtin/stash: fix leak in `show_stash()` revision: free diff options builtin/log: fix leaking commit list in git-cherry(1) merge-recursive: fix memory leak when finalizing merge builtin/merge-recursive: fix leaking object ID bases builtin/difftool: plug memory leaks in `run_dir_diff()` object-name: free leaking object contexts ...
Diffstat (limited to 'builtin')
-rw-r--r--builtin/am.c7
-rw-r--r--builtin/archive.c7
-rw-r--r--builtin/blame.c8
-rw-r--r--builtin/cat-file.c17
-rw-r--r--builtin/clone.c3
-rw-r--r--builtin/commit-tree.c11
-rw-r--r--builtin/commit.c10
-rw-r--r--builtin/difftool.c3
-rw-r--r--builtin/fmt-merge-msg.c4
-rw-r--r--builtin/grep.c4
-rw-r--r--builtin/log.c16
-rw-r--r--builtin/ls-tree.c3
-rw-r--r--builtin/merge-recursive.c6
-rw-r--r--builtin/merge-tree.c1
-rw-r--r--builtin/merge.c18
-rw-r--r--builtin/multi-pack-index.c13
-rw-r--r--builtin/replay.c14
-rw-r--r--builtin/rev-list.c2
-rw-r--r--builtin/rev-parse.c55
-rw-r--r--builtin/shortlog.c5
-rw-r--r--builtin/sparse-checkout.c1
-rw-r--r--builtin/stash.c23
22 files changed, 147 insertions, 84 deletions
diff --git a/builtin/am.c b/builtin/am.c
index 8f9619ea3a..370f5593f2 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -1573,8 +1573,8 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
*/
static int fall_back_threeway(const struct am_state *state, const char *index_path)
{
- struct object_id orig_tree, their_tree, our_tree;
- const struct object_id *bases[1] = { &orig_tree };
+ struct object_id their_tree, our_tree;
+ struct object_id bases[1] = { 0 };
struct merge_options o;
struct commit *result;
char *their_tree_name;
@@ -1588,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
discard_index(the_repository->index);
read_index_from(the_repository->index, index_path, get_git_dir());
- if (write_index_as_tree(&orig_tree, the_repository->index, index_path, 0, NULL))
+ if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL))
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
say(state, stdout, _("Using index info to reconstruct a base tree..."));
@@ -1718,6 +1718,7 @@ static void do_commit(const struct am_state *state)
run_hooks("post-applypatch");
+ free_commit_list(parents);
strbuf_release(&sb);
}
diff --git a/builtin/archive.c b/builtin/archive.c
index 7234607aaa..b50981504f 100644
--- a/builtin/archive.c
+++ b/builtin/archive.c
@@ -90,6 +90,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
N_("path to the remote git-upload-archive command")),
OPT_END()
};
+ int ret;
argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
@@ -104,6 +105,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
- UNLEAK(output);
- return write_archive(argc, argv, prefix, the_repository, output, 0);
+ ret = write_archive(argc, argv, prefix, the_repository, output, 0);
+
+ free(output);
+ return ret;
}
diff --git a/builtin/blame.c b/builtin/blame.c
index babc147d67..35e975fb13 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -67,7 +67,7 @@ static int no_whole_file_rename;
static int show_progress;
static char repeated_meta_color[COLOR_MAXLEN];
static int coloring_mode;
-static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP;
+static struct string_list ignore_revs_file_list = STRING_LIST_INIT_DUP;
static int mark_unblamable_lines;
static int mark_ignored_lines;
@@ -687,7 +687,7 @@ static unsigned parse_score(const char *arg)
return score;
}
-static const char *add_prefix(const char *prefix, const char *path)
+static char *add_prefix(const char *prefix, const char *path)
{
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
}
@@ -725,6 +725,7 @@ static int git_blame_config(const char *var, const char *value,
if (ret)
return ret;
string_list_insert(&ignore_revs_file_list, str);
+ free(str);
return 0;
}
if (!strcmp(var, "blame.markunblamablelines")) {
@@ -866,7 +867,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,
int cmd_blame(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
- const char *path;
+ char *path = NULL;
struct blame_scoreboard sb;
struct blame_origin *o;
struct blame_entry *ent = NULL;
@@ -1227,6 +1228,7 @@ parse_done:
}
cleanup:
+ free(path);
cleanup_scoreboard(&sb);
release_revisions(&revs);
return 0;
diff --git a/builtin/cat-file.c b/builtin/cat-file.c
index 43a1d7ac49..18fe58d6b8 100644
--- a/builtin/cat-file.c
+++ b/builtin/cat-file.c
@@ -102,7 +102,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
enum object_type type;
char *buf;
unsigned long size;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
struct object_info oi = OBJECT_INFO_INIT;
struct strbuf sb = STRBUF_INIT;
unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
@@ -163,7 +163,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
goto cleanup;
case 'e':
- return !repo_has_object_file(the_repository, &oid);
+ ret = !repo_has_object_file(the_repository, &oid);
+ goto cleanup;
case 'w':
@@ -268,7 +269,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
ret = 0;
cleanup:
free(buf);
- free(obj_context.path);
+ object_context_release(&obj_context);
return ret;
}
@@ -520,7 +521,7 @@ static void batch_one_object(const char *obj_name,
struct batch_options *opt,
struct expand_data *data)
{
- struct object_context ctx;
+ struct object_context ctx = {0};
int flags =
GET_OID_HASH_ANY |
(opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
@@ -557,7 +558,8 @@ static void batch_one_object(const char *obj_name,
break;
}
fflush(stdout);
- return;
+
+ goto out;
}
if (ctx.mode == 0) {
@@ -565,10 +567,13 @@ static void batch_one_object(const char *obj_name,
(uintmax_t)ctx.symlink_path.len,
opt->output_delim, ctx.symlink_path.buf, opt->output_delim);
fflush(stdout);
- return;
+ goto out;
}
batch_object_write(obj_name, scratch, opt, data, NULL, 0);
+
+out:
+ object_context_release(&ctx);
}
struct object_cb_data {
diff --git a/builtin/clone.c b/builtin/clone.c
index 80ef2bfca8..af6017d41a 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -533,7 +533,8 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
if (!option_branch)
remote_head = guess_remote_head(head, refs, 0);
else {
- local_refs = NULL;
+ free_one_ref(head);
+ local_refs = head = NULL;
tail = &local_refs;
remote_head = copy_ref(find_remote_branch(refs, option_branch));
}
diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c
index 1bb7819839..84bb450222 100644
--- a/builtin/commit-tree.c
+++ b/builtin/commit-tree.c
@@ -111,6 +111,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
+ int ret;
git_config(git_default_config, NULL);
@@ -132,11 +133,15 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,
NULL, sign_commit)) {
- strbuf_release(&buffer);
- return 1;
+ ret = 1;
+ goto out;
}
printf("%s\n", oid_to_hex(&commit_oid));
+ ret = 0;
+
+out:
+ free_commit_list(parents);
strbuf_release(&buffer);
- return 0;
+ return ret;
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 75c741173e..dec78dfb86 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -106,7 +106,8 @@ static enum {
COMMIT_PARTIAL
} commit_style;
-static const char *logfile, *force_author;
+static const char *force_author;
+static char *logfile;
static char *template_file;
/*
* The _message variables are commit names from which to take
@@ -1309,7 +1310,7 @@ static int parse_and_validate_options(int argc, const char *argv[],
!!use_message, "-C",
!!logfile, "-F");
if (use_message || edit_message || logfile ||fixup_message || have_option_m)
- template_file = NULL;
+ FREE_AND_NULL(template_file);
if (edit_message)
use_message = edit_message;
if (amend && !use_message && !fixup_message)
@@ -1847,7 +1848,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
rollback_index_files();
die(_("failed to write commit object"));
}
- free_commit_extra_headers(extra);
if (update_head_with_reflog(current_head, &oid, reflog_msg, &sb,
&err)) {
@@ -1889,8 +1889,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
apply_autostash_ref(the_repository, "MERGE_AUTOSTASH");
cleanup:
+ free_commit_extra_headers(extra);
+ free_commit_list(parents);
strbuf_release(&author_ident);
strbuf_release(&err);
strbuf_release(&sb);
+ free(logfile);
+ free(template_file);
return ret;
}
diff --git a/builtin/difftool.c b/builtin/difftool.c
index a1794b7eed..dcc68e190c 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -662,6 +662,9 @@ finish:
free(lbase_dir);
free(rbase_dir);
+ strbuf_release(&info);
+ strbuf_release(&lpath);
+ strbuf_release(&rpath);
strbuf_release(&ldir);
strbuf_release(&rdir);
strbuf_release(&wtdir);
diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c
index 0f9855b680..957786d1b3 100644
--- a/builtin/fmt-merge-msg.c
+++ b/builtin/fmt-merge-msg.c
@@ -11,7 +11,7 @@ static const char * const fmt_merge_msg_usage[] = {
int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
{
- const char *inpath = NULL;
+ char *inpath = NULL;
const char *message = NULL;
char *into_name = NULL;
int shortlog_len = -1;
@@ -66,5 +66,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
if (ret)
return ret;
write_in_full(STDOUT_FILENO, output.buf, output.len);
+
+ free(inpath);
return 0;
}
diff --git a/builtin/grep.c b/builtin/grep.c
index 5777ba82a9..dfc3c3e8bd 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -1114,7 +1114,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
struct object_id oid;
- struct object_context oc;
+ struct object_context oc = {0};
struct object *object;
if (!strcmp(arg, "--")) {
@@ -1140,7 +1140,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!seen_dashdash)
verify_non_filename(prefix, arg);
add_object_array_with_path(object, arg, &list, oc.mode, oc.path);
- free(oc.path);
+ object_context_release(&oc);
}
/*
diff --git a/builtin/log.c b/builtin/log.c
index 1b43b604a2..4d4b60caa7 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -682,7 +682,7 @@ static void show_tagger(const char *buf, struct rev_info *rev)
static int show_blob_object(const struct object_id *oid, struct rev_info *rev, const char *obj_name)
{
struct object_id oidc;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
char *buf;
unsigned long size;
@@ -698,7 +698,7 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
if (!obj_context.path ||
!textconv_object(the_repository, obj_context.path,
obj_context.mode, &oidc, 1, &buf, &size)) {
- free(obj_context.path);
+ object_context_release(&obj_context);
return stream_blob_to_fd(1, oid, NULL, 0);
}
@@ -706,7 +706,7 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
die(_("git show %s: bad file"), obj_name);
write_or_die(1, buf, size);
- free(obj_context.path);
+ object_context_release(&obj_context);
return 0;
}
@@ -2021,7 +2021,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
const char *rfc = NULL;
int creation_factor = -1;
const char *signature = git_version_string;
- const char *signature_file_arg = NULL;
+ char *signature_file_arg = NULL;
struct keep_callback_data keep_callback_data = {
.cfg = &cfg,
.revs = &rev,
@@ -2561,6 +2561,8 @@ done:
strbuf_release(&rdiff1);
strbuf_release(&rdiff2);
strbuf_release(&rdiff_title);
+ free(description_file);
+ free(signature_file_arg);
free(to_free);
free(rev.message_id);
if (rev.ref_message_ids)
@@ -2675,16 +2677,16 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
commit_list_insert(commit, &list);
}
- while (list) {
+ for (struct commit_list *l = list; l; l = l->next) {
char sign = '+';
- commit = list->item;
+ commit = l->item;
if (has_commit_patch_id(commit, &ids))
sign = '-';
print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
- list = list->next;
}
+ free_commit_list(list);
free_patch_ids(&ids);
return 0;
}
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 7bf84b235c..bf372c67d7 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -367,7 +367,7 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
OPT_END()
};
struct ls_tree_cmdmode_to_fmt *m2f = ls_tree_cmdmode_format;
- struct object_context obj_context;
+ struct object_context obj_context = {0};
int ret;
git_config(git_default_config, NULL);
@@ -441,5 +441,6 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
ret = !!read_tree(the_repository, tree, &options.pathspec, fn, &options);
clear_pathspec(&options.pathspec);
+ object_context_release(&obj_context);
return ret;
}
diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c
index c2ce044a20..82bebea15b 100644
--- a/builtin/merge-recursive.c
+++ b/builtin/merge-recursive.c
@@ -23,7 +23,7 @@ static char *better_branch_name(const char *branch)
int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
{
- const struct object_id *bases[21];
+ struct object_id bases[21];
unsigned bases_count = 0;
int i, failed;
struct object_id h1, h2;
@@ -49,10 +49,8 @@ int cmd_merge_recursive(int argc, const char **argv, const char *prefix UNUSED)
continue;
}
if (bases_count < ARRAY_SIZE(bases)-1) {
- struct object_id *oid = xmalloc(sizeof(struct object_id));
- if (repo_get_oid(the_repository, argv[i], oid))
+ if (repo_get_oid(the_repository, argv[i], &bases[bases_count++]))
die(_("could not parse object '%s'"), argv[i]);
- bases[bases_count++] = oid;
}
else
warning(Q_("cannot handle more than %d base. "
diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c
index 1082d919fd..dab2fdc2a6 100644
--- a/builtin/merge-tree.c
+++ b/builtin/merge-tree.c
@@ -482,6 +482,7 @@ static int real_merge(struct merge_tree_options *o,
die(_("refusing to merge unrelated histories"));
merge_bases = reverse_commit_list(merge_bases);
merge_incore_recursive(&opt, merge_bases, parent1, parent2, &result);
+ free_commit_list(merge_bases);
}
if (result.clean < 0)
diff --git a/builtin/merge.c b/builtin/merge.c
index 66a4fa72e1..9fba27d85d 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -164,7 +164,7 @@ static struct strategy *get_strategy(const char *name)
{
int i;
struct strategy *ret;
- static struct cmdnames main_cmds, other_cmds;
+ static struct cmdnames main_cmds = {0}, other_cmds = {0};
static int loaded;
char *default_strategy = getenv("GIT_TEST_MERGE_ALGORITHM");
@@ -182,10 +182,9 @@ static struct strategy *get_strategy(const char *name)
return &all_strategy[i];
if (!loaded) {
- struct cmdnames not_strategies;
+ struct cmdnames not_strategies = {0};
loaded = 1;
- memset(&not_strategies, 0, sizeof(struct cmdnames));
load_command_list("git-merge-", &main_cmds, &other_cmds);
for (i = 0; i < main_cmds.cnt; i++) {
int j, found = 0;
@@ -197,6 +196,8 @@ static struct strategy *get_strategy(const char *name)
add_cmdname(&not_strategies, ent->name, ent->len);
}
exclude_cmds(&main_cmds, &not_strategies);
+
+ cmdnames_release(&not_strategies);
}
if (!is_in_cmdlist(&main_cmds, name) && !is_in_cmdlist(&other_cmds, name)) {
fprintf(stderr, _("Could not find merge strategy '%s'.\n"), name);
@@ -216,6 +217,9 @@ static struct strategy *get_strategy(const char *name)
CALLOC_ARRAY(ret, 1);
ret->name = xstrdup(name);
ret->attr = NO_TRIVIAL;
+
+ cmdnames_release(&main_cmds);
+ cmdnames_release(&other_cmds);
return ret;
}
@@ -745,6 +749,8 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
else
clean = merge_recursive(&o, head, remoteheads->item,
reversed, &result);
+ free_commit_list(reversed);
+
if (clean < 0) {
rollback_lock_file(&lock);
return 2;
@@ -898,7 +904,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
{
struct object_id result_tree, result_commit;
- struct commit_list *parents, **pptr = &parents;
+ struct commit_list *parents = NULL, **pptr = &parents;
if (repo_refresh_and_write_index(the_repository, REFRESH_QUIET,
SKIP_IF_UNCHANGED, 0, NULL, NULL,
@@ -914,7 +920,9 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
&result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
finish(head, remoteheads, &result_commit, "In-index merge");
+
remove_merge_branch_state(the_repository);
+ free_commit_list(parents);
return 0;
}
@@ -940,8 +948,10 @@ static int finish_automerge(struct commit *head,
die(_("failed to write commit object"));
strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy);
finish(head, remoteheads, &result_commit, buf.buf);
+
strbuf_release(&buf);
remove_merge_branch_state(the_repository);
+ free_commit_list(parents);
return 0;
}
diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c
index 8360932d2e..9cf1a32d65 100644
--- a/builtin/multi-pack-index.c
+++ b/builtin/multi-pack-index.c
@@ -50,7 +50,7 @@ static char const * const builtin_multi_pack_index_usage[] = {
static struct opts_multi_pack_index {
char *object_dir;
const char *preferred_pack;
- const char *refs_snapshot;
+ char *refs_snapshot;
unsigned long batch_size;
unsigned flags;
int stdin_packs;
@@ -135,6 +135,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
N_("refs snapshot for selecting bitmap commits")),
OPT_END(),
};
+ int ret;
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
@@ -157,7 +158,6 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
if (opts.stdin_packs) {
struct string_list packs = STRING_LIST_INIT_DUP;
- int ret;
read_packs_from_stdin(&packs);
@@ -166,12 +166,17 @@ static int cmd_multi_pack_index_write(int argc, const char **argv,
opts.refs_snapshot, opts.flags);
string_list_clear(&packs, 0);
+ free(opts.refs_snapshot);
return ret;
}
- return write_midx_file(opts.object_dir, opts.preferred_pack,
- opts.refs_snapshot, opts.flags);
+
+ ret = write_midx_file(opts.object_dir, opts.preferred_pack,
+ opts.refs_snapshot, opts.flags);
+
+ free(opts.refs_snapshot);
+ return ret;
}
static int cmd_multi_pack_index_verify(int argc, const char **argv,
diff --git a/builtin/replay.c b/builtin/replay.c
index 6bf0691f15..0448326636 100644
--- a/builtin/replay.c
+++ b/builtin/replay.c
@@ -52,11 +52,11 @@ static struct commit *create_commit(struct tree *tree,
struct commit *parent)
{
struct object_id ret;
- struct object *obj;
+ struct object *obj = NULL;
struct commit_list *parents = NULL;
char *author;
char *sign_commit = NULL; /* FIXME: cli users might want to sign again */
- struct commit_extra_header *extra;
+ struct commit_extra_header *extra = NULL;
struct strbuf msg = STRBUF_INIT;
const char *out_enc = get_commit_output_encoding();
const char *message = repo_logmsg_reencode(the_repository, based_on,
@@ -73,12 +73,16 @@ static struct commit *create_commit(struct tree *tree,
if (commit_tree_extended(msg.buf, msg.len, &tree->object.oid, parents,
&ret, author, NULL, sign_commit, extra)) {
error(_("failed to write commit object"));
- return NULL;
+ goto out;
}
- free(author);
- strbuf_release(&msg);
obj = parse_object(the_repository, &ret);
+
+out:
+ free_commit_extra_headers(extra);
+ free_commit_list(parents);
+ strbuf_release(&msg);
+ free(author);
return (struct commit *)obj;
}
diff --git a/builtin/rev-list.c b/builtin/rev-list.c
index 77803727e0..97d077a994 100644
--- a/builtin/rev-list.c
+++ b/builtin/rev-list.c
@@ -508,6 +508,8 @@ static int try_bitmap_disk_usage(struct rev_info *revs,
size_from_bitmap = get_disk_usage_from_bitmap(bitmap_git, revs);
print_disk_usage(size_from_bitmap);
+
+ free_bitmap_index(bitmap_git);
return 0;
}
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 1e2919fd81..2e64f5bda7 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -423,12 +423,12 @@ static char *findspace(const char *s)
static int cmd_parseopt(int argc, const char **argv, const char *prefix)
{
- static int keep_dashdash = 0, stop_at_non_option = 0;
- static char const * const parseopt_usage[] = {
+ int keep_dashdash = 0, stop_at_non_option = 0;
+ char const * const parseopt_usage[] = {
N_("git rev-parse --parseopt [<options>] -- [<args>...]"),
NULL
};
- static struct option parseopt_opts[] = {
+ struct option parseopt_opts[] = {
OPT_BOOL(0, "keep-dashdash", &keep_dashdash,
N_("keep the `--` passed as an arg")),
OPT_BOOL(0, "stop-at-non-option", &stop_at_non_option,
@@ -438,12 +438,11 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
N_("output in stuck long form")),
OPT_END(),
};
- static const char * const flag_chars = "*=?!";
-
struct strbuf sb = STRBUF_INIT, parsed = STRBUF_INIT;
- const char **usage = NULL;
+ struct strvec longnames = STRVEC_INIT;
+ struct strvec usage = STRVEC_INIT;
struct option *opts = NULL;
- int onb = 0, osz = 0, unb = 0, usz = 0;
+ size_t opts_nr = 0, opts_alloc = 0;
strbuf_addstr(&parsed, "set --");
argc = parse_options(argc, argv, prefix, parseopt_opts, parseopt_usage,
@@ -453,16 +452,16 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
/* get the usage up to the first line with a -- on it */
for (;;) {
+ strbuf_reset(&sb);
if (strbuf_getline(&sb, stdin) == EOF)
die(_("premature end of input"));
- ALLOC_GROW(usage, unb + 1, usz);
if (!strcmp("--", sb.buf)) {
- if (unb < 1)
+ if (!usage.nr)
die(_("no usage string given before the `--' separator"));
- usage[unb] = NULL;
break;
}
- usage[unb++] = strbuf_detach(&sb, NULL);
+
+ strvec_push(&usage, sb.buf);
}
/* parse: (<short>|<short>,<long>|<long>)[*=?!]*<arghint>? SP+ <help> */
@@ -474,10 +473,10 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
if (!sb.len)
continue;
- ALLOC_GROW(opts, onb + 1, osz);
- memset(opts + onb, 0, sizeof(opts[onb]));
+ ALLOC_GROW(opts, opts_nr + 1, opts_alloc);
+ memset(opts + opts_nr, 0, sizeof(*opts));
- o = &opts[onb++];
+ o = &opts[opts_nr++];
help = findspace(sb.buf);
if (!help || sb.buf == help) {
o->type = OPTION_GROUP;
@@ -494,20 +493,22 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
o->callback = &parseopt_dump;
/* name(s) */
- s = strpbrk(sb.buf, flag_chars);
+ s = strpbrk(sb.buf, "*=?!");
if (!s)
s = help;
if (s == sb.buf)
die(_("missing opt-spec before option flags"));
- if (s - sb.buf == 1) /* short option only */
+ if (s - sb.buf == 1) { /* short option only */
o->short_name = *sb.buf;
- else if (sb.buf[1] != ',') /* long option only */
- o->long_name = xmemdupz(sb.buf, s - sb.buf);
- else {
+ } else if (sb.buf[1] != ',') { /* long option only */
+ o->long_name = strvec_pushf(&longnames, "%.*s",
+ (int)(s - sb.buf), sb.buf);
+ } else {
o->short_name = *sb.buf;
- o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
+ o->long_name = strvec_pushf(&longnames, "%.*s",
+ (int)(s - sb.buf - 2), sb.buf + 2);
}
/* flags */
@@ -537,9 +538,9 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
strbuf_release(&sb);
/* put an OPT_END() */
- ALLOC_GROW(opts, onb + 1, osz);
- memset(opts + onb, 0, sizeof(opts[onb]));
- argc = parse_options(argc, argv, prefix, opts, usage,
+ ALLOC_GROW(opts, opts_nr + 1, opts_alloc);
+ memset(opts + opts_nr, 0, sizeof(*opts));
+ argc = parse_options(argc, argv, prefix, opts, usage.v,
(keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0) |
(stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0) |
PARSE_OPT_SHELL_EVAL);
@@ -547,7 +548,13 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
strbuf_addstr(&parsed, " --");
sq_quote_argv(&parsed, argv);
puts(parsed.buf);
+
strbuf_release(&parsed);
+ strbuf_release(&sb);
+ strvec_clear(&longnames);
+ strvec_clear(&usage);
+ free((char *) opts->help);
+ free(opts);
return 0;
}
@@ -1121,6 +1128,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!get_oid_with_context(the_repository, name,
flags, &oid, &unused)) {
+ object_context_release(&unused);
if (output_algo)
repo_oid_to_algop(the_repository, &oid,
output_algo, &oid);
@@ -1130,6 +1138,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
show_rev(type, &oid, name);
continue;
}
+ object_context_release(&unused);
if (verify)
die_no_single_rev(quiet);
if (has_dashdash)
diff --git a/builtin/shortlog.c b/builtin/shortlog.c
index d4daf31e22..5bde7c68c2 100644
--- a/builtin/shortlog.c
+++ b/builtin/shortlog.c
@@ -460,11 +460,8 @@ parse_done:
else
get_from_rev(&rev, &log);
- release_revisions(&rev);
-
shortlog_output(&log);
- if (log.file != stdout)
- fclose(log.file);
+ release_revisions(&rev);
return 0;
}
diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c
index 3f2bfce8fa..2604ab04df 100644
--- a/builtin/sparse-checkout.c
+++ b/builtin/sparse-checkout.c
@@ -1026,6 +1026,7 @@ static int sparse_checkout_check_rules(int argc, const char **argv, const char *
ret = check_rules(&pl, check_rules_opts.null_termination);
clear_pattern_list(&pl);
+ free(check_rules_opts.rules_file);
return ret;
}
diff --git a/builtin/stash.c b/builtin/stash.c
index 7859bc0866..46b981c4dd 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -975,7 +975,9 @@ static int show_stash(int argc, const char **argv, const char *prefix)
log_tree_diff_flush(&rev);
ret = diff_result_code(&rev.diffopt);
+
cleanup:
+ strvec_clear(&revision_args);
strvec_clear(&stash_args);
free_stash_info(&info);
release_revisions(&rev);
@@ -1018,13 +1020,14 @@ static int store_stash(int argc, const char **argv, const char *prefix)
int quiet = 0;
const char *stash_msg = NULL;
struct object_id obj;
- struct object_context dummy;
+ struct object_context dummy = {0};
struct option options[] = {
OPT__QUIET(&quiet, N_("be quiet")),
OPT_STRING('m', "message", &stash_msg, "message",
N_("stash message")),
OPT_END()
};
+ int ret;
argc = parse_options(argc, argv, prefix, options,
git_stash_store_usage,
@@ -1043,10 +1046,15 @@ static int store_stash(int argc, const char **argv, const char *prefix)
if (!quiet)
fprintf_ln(stderr, _("Cannot update %s with %s"),
ref_stash, argv[0]);
- return -1;
+ ret = -1;
+ goto out;
}
- return do_store_stash(&obj, stash_msg, quiet);
+ ret = do_store_stash(&obj, stash_msg, quiet);
+
+out:
+ object_context_release(&dummy);
+ return ret;
}
static void add_pathspecs(struct strvec *args,
@@ -1408,6 +1416,9 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
goto done;
}
+ free_commit_list(parents);
+ parents = NULL;
+
if (include_untracked) {
if (save_untracked_files(info, &msg, untracked_files)) {
if (!quiet)
@@ -1453,11 +1464,6 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b
else
strbuf_insertf(stash_msg_buf, 0, "On %s: ", branch_name);
- /*
- * `parents` will be empty after calling `commit_tree()`, so there is
- * no need to call `free_commit_list()`
- */
- parents = NULL;
if (untracked_commit_option)
commit_list_insert(lookup_commit(the_repository,
&info->u_commit),
@@ -1479,6 +1485,7 @@ done:
strbuf_release(&commit_tree_label);
strbuf_release(&msg);
strbuf_release(&untracked_files);
+ free_commit_list(parents);
return ret;
}