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
  ...
This commit is contained in:
Junio C Hamano 2024-07-08 14:53:10 -07:00
commit 3997614c24
130 changed files with 591 additions and 272 deletions

88
apply.c
View File

@ -137,6 +137,7 @@ void clear_apply_state(struct apply_state *state)
strset_clear(&state->removed_symlinks);
strset_clear(&state->kept_symlinks);
strbuf_release(&state->root);
FREE_AND_NULL(state->fake_ancestor);
/* &state->fn_table is cleared at the end of apply_patch() */
}
@ -2495,18 +2496,21 @@ static int match_fragment(struct apply_state *state,
int match_beginning, int match_end)
{
int i;
char *fixed_buf, *buf, *orig, *target;
struct strbuf fixed;
size_t fixed_len, postlen;
const char *orig, *target;
struct strbuf fixed = STRBUF_INIT;
size_t postlen;
int preimage_limit;
int ret;
if (preimage->nr + current_lno <= img->nr) {
/*
* The hunk falls within the boundaries of img.
*/
preimage_limit = preimage->nr;
if (match_end && (preimage->nr + current_lno != img->nr))
return 0;
if (match_end && (preimage->nr + current_lno != img->nr)) {
ret = 0;
goto out;
}
} else if (state->ws_error_action == correct_ws_error &&
(ws_rule & WS_BLANK_AT_EOF)) {
/*
@ -2523,17 +2527,23 @@ static int match_fragment(struct apply_state *state,
* we are not removing blanks at the end, so we
* should reject the hunk at this position.
*/
return 0;
ret = 0;
goto out;
}
if (match_beginning && current_lno)
return 0;
if (match_beginning && current_lno) {
ret = 0;
goto out;
}
/* Quick hash check */
for (i = 0; i < preimage_limit; i++)
for (i = 0; i < preimage_limit; i++) {
if ((img->line[current_lno + i].flag & LINE_PATCHED) ||
(preimage->line[i].hash != img->line[current_lno + i].hash))
return 0;
(preimage->line[i].hash != img->line[current_lno + i].hash)) {
ret = 0;
goto out;
}
}
if (preimage_limit == preimage->nr) {
/*
@ -2546,8 +2556,10 @@ static int match_fragment(struct apply_state *state,
if ((match_end
? (current + preimage->len == img->len)
: (current + preimage->len <= img->len)) &&
!memcmp(img->buf + current, preimage->buf, preimage->len))
return 1;
!memcmp(img->buf + current, preimage->buf, preimage->len)) {
ret = 1;
goto out;
}
} else {
/*
* The preimage extends beyond the end of img, so
@ -2556,7 +2568,7 @@ static int match_fragment(struct apply_state *state,
* There must be one non-blank context line that match
* a line before the end of img.
*/
char *buf_end;
const char *buf, *buf_end;
buf = preimage->buf;
buf_end = buf;
@ -2566,8 +2578,10 @@ static int match_fragment(struct apply_state *state,
for ( ; buf < buf_end; buf++)
if (!isspace(*buf))
break;
if (buf == buf_end)
return 0;
if (buf == buf_end) {
ret = 0;
goto out;
}
}
/*
@ -2575,12 +2589,16 @@ static int match_fragment(struct apply_state *state,
* fuzzy matching. We collect all the line length information because
* we need it to adjust whitespace if we match.
*/
if (state->ws_ignore_action == ignore_ws_change)
return line_by_line_fuzzy_match(img, preimage, postimage,
current, current_lno, preimage_limit);
if (state->ws_ignore_action == ignore_ws_change) {
ret = line_by_line_fuzzy_match(img, preimage, postimage,
current, current_lno, preimage_limit);
goto out;
}
if (state->ws_error_action != correct_ws_error)
return 0;
if (state->ws_error_action != correct_ws_error) {
ret = 0;
goto out;
}
/*
* The hunk does not apply byte-by-byte, but the hash says
@ -2609,7 +2627,7 @@ static int match_fragment(struct apply_state *state,
* but in this loop we will only handle the part of the
* preimage that falls within the file.
*/
strbuf_init(&fixed, preimage->len + 1);
strbuf_grow(&fixed, preimage->len + 1);
orig = preimage->buf;
target = img->buf + current;
for (i = 0; i < preimage_limit; i++) {
@ -2645,8 +2663,10 @@ static int match_fragment(struct apply_state *state,
postlen += tgtfix.len;
strbuf_release(&tgtfix);
if (!match)
goto unmatch_exit;
if (!match) {
ret = 0;
goto out;
}
orig += oldlen;
target += tgtlen;
@ -2667,9 +2687,13 @@ static int match_fragment(struct apply_state *state,
/* Try fixing the line in the preimage */
ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);
for (j = fixstart; j < fixed.len; j++)
if (!isspace(fixed.buf[j]))
goto unmatch_exit;
for (j = fixstart; j < fixed.len; j++) {
if (!isspace(fixed.buf[j])) {
ret = 0;
goto out;
}
}
orig += oldlen;
}
@ -2679,16 +2703,16 @@ static int match_fragment(struct apply_state *state,
* has whitespace breakages unfixed, and fixing them makes the
* hunk match. Update the context lines in the postimage.
*/
fixed_buf = strbuf_detach(&fixed, &fixed_len);
if (postlen < postimage->len)
postlen = 0;
update_pre_post_images(preimage, postimage,
fixed_buf, fixed_len, postlen);
return 1;
fixed.buf, fixed.len, postlen);
unmatch_exit:
ret = 1;
out:
strbuf_release(&fixed);
return 0;
return ret;
}
static int find_pos(struct apply_state *state,

View File

@ -59,7 +59,7 @@ struct apply_state {
struct repository *repo;
const char *index_file;
enum apply_verbosity apply_verbosity;
const char *fake_ancestor;
char *fake_ancestor;
const char *patch_input_file;
int line_termination;
struct strbuf root;

View File

@ -2930,6 +2930,10 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb)
void cleanup_scoreboard(struct blame_scoreboard *sb)
{
free(sb->lineno);
clear_prio_queue(&sb->commits);
oidset_clear(&sb->ignore_list);
if (sb->bloom_data) {
int i;
for (i = 0; i < sb->bloom_data->nr; i++) {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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 {

View File

@ -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));
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}
/*

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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. "

View File

@ -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)

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -502,6 +502,7 @@ int create_bundle(struct repository *r, const char *path,
struct rev_info revs, revs_copy;
int min_version = 2;
struct bundle_prerequisites_info bpi;
int ret;
int i;
/* init revs to list objects for pack-objects later */
@ -527,8 +528,8 @@ int create_bundle(struct repository *r, const char *path,
min_version = 3;
if (argc > 1) {
error(_("unrecognized argument: %s"), argv[1]);
goto err;
ret = error(_("unrecognized argument: %s"), argv[1]);
goto out;
}
bundle_to_stdout = !strcmp(path, "-");
@ -593,23 +594,31 @@ int create_bundle(struct repository *r, const char *path,
/* write bundle refs */
ref_count = write_bundle_refs(bundle_fd, &revs_copy);
if (!ref_count)
if (!ref_count) {
die(_("Refusing to create empty bundle."));
else if (ref_count < 0)
goto err;
} else if (ref_count < 0) {
ret = -1;
goto out;
}
/* write pack */
if (write_pack_data(bundle_fd, &revs_copy, pack_options))
goto err;
if (write_pack_data(bundle_fd, &revs_copy, pack_options)) {
ret = -1;
goto out;
}
if (!bundle_to_stdout) {
if (commit_lock_file(&lock))
die_errno(_("cannot create '%s'"), path);
}
return 0;
err:
ret = 0;
out:
object_array_clear(&revs_copy.pending);
release_revisions(&revs);
rollback_lock_file(&lock);
return -1;
return ret;
}
int unbundle(struct repository *r, struct bundle_header *header,

View File

@ -682,7 +682,7 @@ unsigned commit_list_count(const struct commit_list *l)
return c;
}
struct commit_list *copy_commit_list(struct commit_list *list)
struct commit_list *copy_commit_list(const struct commit_list *list)
{
struct commit_list *head = NULL;
struct commit_list **pp = &head;
@ -1264,7 +1264,7 @@ int remove_signature(struct strbuf *buf)
return sigs[0].start != NULL;
}
static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
static void handle_signed_tag(const struct commit *parent, struct commit_extra_header ***tail)
{
struct merge_remote_desc *desc;
struct commit_extra_header *mergetag;
@ -1361,17 +1361,17 @@ void verify_merge_signature(struct commit *commit, int verbosity,
signature_check_clear(&signature_check);
}
void append_merge_tag_headers(struct commit_list *parents,
void append_merge_tag_headers(const struct commit_list *parents,
struct commit_extra_header ***tail)
{
while (parents) {
struct commit *parent = parents->item;
const struct commit *parent = parents->item;
handle_signed_tag(parent, tail);
parents = parents->next;
}
}
static int convert_commit_extra_headers(struct commit_extra_header *orig,
static int convert_commit_extra_headers(const struct commit_extra_header *orig,
struct commit_extra_header **result)
{
const struct git_hash_algo *compat = the_repository->compat_hash_algo;
@ -1405,7 +1405,7 @@ static int convert_commit_extra_headers(struct commit_extra_header *orig,
}
static void add_extra_header(struct strbuf *buffer,
struct commit_extra_header *extra)
const struct commit_extra_header *extra)
{
strbuf_addstr(buffer, extra->key);
if (extra->len)
@ -1519,7 +1519,7 @@ void free_commit_extra_headers(struct commit_extra_header *extra)
}
int commit_tree(const char *msg, size_t msg_len, const struct object_id *tree,
struct commit_list *parents, struct object_id *ret,
const struct commit_list *parents, struct object_id *ret,
const char *author, const char *sign_commit)
{
struct commit_extra_header *extra = NULL, **tail = &extra;
@ -1651,7 +1651,7 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
const struct object_id *tree,
const struct object_id *parents, size_t parents_len,
const char *author, const char *committer,
struct commit_extra_header *extra)
const struct commit_extra_header *extra)
{
int encoding_is_utf8;
size_t i;
@ -1692,10 +1692,10 @@ static void write_commit_tree(struct strbuf *buffer, const char *msg, size_t msg
int commit_tree_extended(const char *msg, size_t msg_len,
const struct object_id *tree,
struct commit_list *parents, struct object_id *ret,
const struct commit_list *parents, struct object_id *ret,
const char *author, const char *committer,
const char *sign_commit,
struct commit_extra_header *extra)
const struct commit_extra_header *extra)
{
struct repository *r = the_repository;
int result = 0;
@ -1717,10 +1717,8 @@ int commit_tree_extended(const char *msg, size_t msg_len,
nparents = commit_list_count(parents);
CALLOC_ARRAY(parent_buf, nparents);
i = 0;
while (parents) {
struct commit *parent = pop_commit(&parents);
oidcpy(&parent_buf[i++], &parent->object.oid);
}
for (const struct commit_list *p = parents; p; p = p->next)
oidcpy(&parent_buf[i++], &p->item->object.oid);
write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra);
if (sign_commit && sign_commit_to_strbuf(&sig, &buffer, sign_commit)) {
@ -1816,7 +1814,7 @@ out:
define_commit_slab(merge_desc_slab, struct merge_remote_desc *);
static struct merge_desc_slab merge_desc_slab = COMMIT_SLAB_INIT(1, merge_desc_slab);
struct merge_remote_desc *merge_remote_util(struct commit *commit)
struct merge_remote_desc *merge_remote_util(const struct commit *commit)
{
return *merge_desc_slab_at(&merge_desc_slab, commit);
}

View File

@ -181,7 +181,7 @@ struct commit_list *commit_list_insert_by_date(struct commit *item,
void commit_list_sort_by_date(struct commit_list **list);
/* Shallow copy of the input list */
struct commit_list *copy_commit_list(struct commit_list *list);
struct commit_list *copy_commit_list(const struct commit_list *list);
/* Modify list in-place to reverse it, returning new head; list will be tail */
struct commit_list *reverse_commit_list(struct commit_list *list);
@ -260,19 +260,19 @@ struct commit_extra_header {
size_t len;
};
void append_merge_tag_headers(struct commit_list *parents,
void append_merge_tag_headers(const struct commit_list *parents,
struct commit_extra_header ***tail);
int commit_tree(const char *msg, size_t msg_len,
const struct object_id *tree,
struct commit_list *parents, struct object_id *ret,
const struct commit_list *parents, struct object_id *ret,
const char *author, const char *sign_commit);
int commit_tree_extended(const char *msg, size_t msg_len,
const struct object_id *tree,
struct commit_list *parents, struct object_id *ret,
const struct commit_list *parents, struct object_id *ret,
const char *author, const char *committer,
const char *sign_commit, struct commit_extra_header *);
const char *sign_commit, const struct commit_extra_header *);
struct commit_extra_header *read_commit_extra_headers(struct commit *, const char **);
@ -301,7 +301,7 @@ struct merge_remote_desc {
struct object *obj; /* the named object, could be a tag */
char name[FLEX_ARRAY];
};
struct merge_remote_desc *merge_remote_util(struct commit *);
struct merge_remote_desc *merge_remote_util(const struct commit *);
void set_merge_remote_desc(struct commit *commit,
const char *name, struct object *obj);

View File

@ -1577,6 +1577,7 @@ static int git_default_core_config(const char *var, const char *value,
if (!strcmp(var, "core.notesref")) {
if (!value)
return config_error_nonbool(var);
free(notes_ref_name);
notes_ref_name = xstrdup(value);
return 0;
}

View File

@ -665,9 +665,11 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
repo_init_revisions(opt->repo, &revs, NULL);
copy_pathspec(&revs.prune_data, &opt->pathspec);
revs.diffopt = *opt;
revs.diffopt.no_free = 1;
if (diff_cache(&revs, tree_oid, NULL, 1))
exit(128);
release_revisions(&revs);
return 0;
}

8
diff.c
View File

@ -6689,8 +6689,10 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
static void diff_free_file(struct diff_options *options)
{
if (options->close_file)
if (options->close_file && options->file) {
fclose(options->file);
options->file = NULL;
}
}
static void diff_free_ignore_regex(struct diff_options *options)
@ -6701,7 +6703,9 @@ static void diff_free_ignore_regex(struct diff_options *options)
regfree(options->ignore_regex[i]);
free(options->ignore_regex[i]);
}
free(options->ignore_regex);
FREE_AND_NULL(options->ignore_regex);
options->ignore_regex_nr = 0;
}
void diff_free(struct diff_options *options)

12
help.c
View File

@ -163,7 +163,7 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len)
cmds->names[cmds->cnt++] = ent;
}
static void clean_cmdnames(struct cmdnames *cmds)
void cmdnames_release(struct cmdnames *cmds)
{
int i;
for (i = 0; i < cmds->cnt; ++i)
@ -365,8 +365,8 @@ void list_all_main_cmds(struct string_list *list)
for (i = 0; i < main_cmds.cnt; i++)
string_list_append(list, main_cmds.names[i]->name);
clean_cmdnames(&main_cmds);
clean_cmdnames(&other_cmds);
cmdnames_release(&main_cmds);
cmdnames_release(&other_cmds);
}
void list_all_other_cmds(struct string_list *list)
@ -381,8 +381,8 @@ void list_all_other_cmds(struct string_list *list)
for (i = 0; i < other_cmds.cnt; i++)
string_list_append(list, other_cmds.names[i]->name);
clean_cmdnames(&main_cmds);
clean_cmdnames(&other_cmds);
cmdnames_release(&main_cmds);
cmdnames_release(&other_cmds);
}
void list_cmds_by_category(struct string_list *list,
@ -695,7 +695,7 @@ const char *help_unknown_cmd(const char *cmd)
if (autocorrect && n == 1 && SIMILAR_ENOUGH(best_similarity)) {
const char *assumed = main_cmds.names[0]->name;
main_cmds.names[0] = NULL;
clean_cmdnames(&main_cmds);
cmdnames_release(&main_cmds);
fprintf_ln(stderr,
_("WARNING: You called a Git command named '%s', "
"which does not exist."),

2
help.h
View File

@ -13,6 +13,8 @@ struct cmdnames {
} **names;
};
void cmdnames_release(struct cmdnames *cmds);
static inline void mput_char(char c, unsigned int num)
{
while (num--)

View File

@ -234,6 +234,8 @@ static const char *parse_range_funcname(
}
regfree(&regexp);
if (xecfg)
xdiff_clear_find_func(xecfg);
free(xecfg);
free(pattern);

View File

@ -544,6 +544,8 @@ static void filter_sparse_oid__init(
filter->filter_data = d;
filter->filter_object_fn = filter_sparse;
filter->free_fn = filter_sparse_free;
object_context_release(&oc);
}
/*

View File

@ -1053,6 +1053,7 @@ static int do_remerge_diff(struct rev_info *opt,
log_tree_diff_flush(opt);
/* Cleanup */
free_commit_list(bases);
cleanup_additional_headers(&opt->diffopt);
strbuf_release(&parent1_desc);
strbuf_release(&parent2_desc);

View File

@ -48,7 +48,7 @@ int merge_ort_nonrecursive(struct merge_options *opt,
int merge_ort_recursive(struct merge_options *opt,
struct commit *side1,
struct commit *side2,
struct commit_list *merge_bases,
const struct commit_list *merge_bases,
struct commit **result)
{
struct tree *head = repo_get_commit_tree(opt->repo, side1);

View File

@ -19,7 +19,7 @@ int merge_ort_nonrecursive(struct merge_options *opt,
int merge_ort_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
struct commit_list *ancestors,
const struct commit_list *ancestors,
struct commit **result);
#endif

View File

@ -5073,11 +5073,12 @@ redo:
* Originally from merge_recursive_internal(); somewhat adapted, though.
*/
static void merge_ort_internal(struct merge_options *opt,
struct commit_list *merge_bases,
const struct commit_list *_merge_bases,
struct commit *h1,
struct commit *h2,
struct merge_result *result)
{
struct commit_list *merge_bases = copy_commit_list(_merge_bases);
struct commit *next;
struct commit *merged_merge_bases;
const char *ancestor_name;
@ -5087,7 +5088,7 @@ static void merge_ort_internal(struct merge_options *opt,
if (repo_get_merge_bases(the_repository, h1, h2,
&merge_bases) < 0) {
result->clean = -1;
return;
goto out;
}
/* See merge-ort.h:merge_incore_recursive() declaration NOTE */
merge_bases = reverse_commit_list(merge_bases);
@ -5131,7 +5132,7 @@ static void merge_ort_internal(struct merge_options *opt,
opt->branch2 = "Temporary merge branch 2";
merge_ort_internal(opt, NULL, prev, next, result);
if (result->clean < 0)
return;
goto out;
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
@ -5154,6 +5155,9 @@ static void merge_ort_internal(struct merge_options *opt,
result);
strbuf_release(&merge_base_abbrev);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
out:
free_commit_list(merge_bases);
}
void merge_incore_nonrecursive(struct merge_options *opt,
@ -5183,7 +5187,7 @@ void merge_incore_nonrecursive(struct merge_options *opt,
}
void merge_incore_recursive(struct merge_options *opt,
struct commit_list *merge_bases,
const struct commit_list *merge_bases,
struct commit *side1,
struct commit *side2,
struct merge_result *result)

View File

@ -59,7 +59,7 @@ struct merge_result {
* first", 2006-08-09)
*/
void merge_incore_recursive(struct merge_options *opt,
struct commit_list *merge_bases,
const struct commit_list *merge_bases,
struct commit *side1,
struct commit *side2,
struct merge_result *result);

View File

@ -242,7 +242,8 @@ enum rename_type {
struct stage_data {
struct diff_filespec stages[4]; /* mostly for oid & mode; maybe path */
struct rename_conflict_info *rename_conflict_info;
unsigned processed:1;
unsigned processed:1,
rename_conflict_info_owned:1;
};
struct rename {
@ -311,6 +312,7 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
ci->ren1->dst_entry->processed = 0;
ci->ren1->dst_entry->rename_conflict_info = ci;
ci->ren1->dst_entry->rename_conflict_info_owned = 1;
if (ren2) {
ci->ren2->dst_entry->rename_conflict_info = ci;
}
@ -3058,6 +3060,10 @@ static void final_cleanup_rename(struct string_list *rename)
for (i = 0; i < rename->nr; i++) {
re = rename->items[i].util;
diff_free_filepair(re->pair);
if (re->src_entry->rename_conflict_info_owned)
FREE_AND_NULL(re->src_entry->rename_conflict_info);
if (re->dst_entry->rename_conflict_info_owned)
FREE_AND_NULL(re->dst_entry->rename_conflict_info);
}
string_list_clear(rename, 1);
free(rename);
@ -3630,15 +3636,16 @@ static int merge_trees_internal(struct merge_options *opt,
static int merge_recursive_internal(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
struct commit_list *merge_bases,
const struct commit_list *_merge_bases,
struct commit **result)
{
struct commit_list *merge_bases = copy_commit_list(_merge_bases);
struct commit_list *iter;
struct commit *merged_merge_bases;
struct tree *result_tree;
int clean;
const char *ancestor_name;
struct strbuf merge_base_abbrev = STRBUF_INIT;
int ret;
if (show(opt, 4)) {
output(opt, 4, _("Merging:"));
@ -3648,8 +3655,10 @@ static int merge_recursive_internal(struct merge_options *opt,
if (!merge_bases) {
if (repo_get_merge_bases(the_repository, h1, h2,
&merge_bases) < 0)
return -1;
&merge_bases) < 0) {
ret = -1;
goto out;
}
merge_bases = reverse_commit_list(merge_bases);
}
@ -3699,14 +3708,18 @@ static int merge_recursive_internal(struct merge_options *opt,
opt->branch1 = "Temporary merge branch 1";
opt->branch2 = "Temporary merge branch 2";
if (merge_recursive_internal(opt, merged_merge_bases, iter->item,
NULL, &merged_merge_bases) < 0)
return -1;
NULL, &merged_merge_bases) < 0) {
ret = -1;
goto out;
}
opt->branch1 = saved_b1;
opt->branch2 = saved_b2;
opt->priv->call_depth--;
if (!merged_merge_bases)
return err(opt, _("merge returned no commit"));
if (!merged_merge_bases) {
ret = err(opt, _("merge returned no commit"));
goto out;
}
}
/*
@ -3723,17 +3736,16 @@ static int merge_recursive_internal(struct merge_options *opt,
repo_read_index(opt->repo);
opt->ancestor = ancestor_name;
clean = merge_trees_internal(opt,
repo_get_commit_tree(opt->repo, h1),
repo_get_commit_tree(opt->repo, h2),
repo_get_commit_tree(opt->repo,
merged_merge_bases),
&result_tree);
strbuf_release(&merge_base_abbrev);
ret = merge_trees_internal(opt,
repo_get_commit_tree(opt->repo, h1),
repo_get_commit_tree(opt->repo, h2),
repo_get_commit_tree(opt->repo,
merged_merge_bases),
&result_tree);
opt->ancestor = NULL; /* avoid accidental re-use of opt->ancestor */
if (clean < 0) {
if (ret < 0) {
flush_output(opt);
return clean;
goto out;
}
if (opt->priv->call_depth) {
@ -3742,7 +3754,11 @@ static int merge_recursive_internal(struct merge_options *opt,
commit_list_insert(h1, &(*result)->parents);
commit_list_insert(h2, &(*result)->parents->next);
}
return clean;
out:
strbuf_release(&merge_base_abbrev);
free_commit_list(merge_bases);
return ret;
}
static int merge_start(struct merge_options *opt, struct tree *head)
@ -3797,6 +3813,9 @@ static void merge_finalize(struct merge_options *opt)
if (show(opt, 2))
diff_warn_rename_limit("merge.renamelimit",
opt->priv->needed_rename_limit, 0);
hashmap_clear_and_free(&opt->priv->current_file_dir_set,
struct path_hashmap_entry, e);
string_list_clear(&opt->priv->df_conflict_file_set, 0);
FREE_AND_NULL(opt->priv);
}
@ -3821,7 +3840,7 @@ int merge_trees(struct merge_options *opt,
int merge_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
struct commit_list *merge_bases,
const struct commit_list *merge_bases,
struct commit **result)
{
int clean;
@ -3863,7 +3882,7 @@ int merge_recursive_generic(struct merge_options *opt,
const struct object_id *head,
const struct object_id *merge,
int num_merge_bases,
const struct object_id **merge_bases,
const struct object_id *merge_bases,
struct commit **result)
{
int clean;
@ -3876,10 +3895,10 @@ int merge_recursive_generic(struct merge_options *opt,
int i;
for (i = 0; i < num_merge_bases; ++i) {
struct commit *base;
if (!(base = get_ref(opt->repo, merge_bases[i],
oid_to_hex(merge_bases[i]))))
if (!(base = get_ref(opt->repo, &merge_bases[i],
oid_to_hex(&merge_bases[i]))))
return err(opt, _("Could not parse object '%s'"),
oid_to_hex(merge_bases[i]));
oid_to_hex(&merge_bases[i]));
commit_list_insert(base, &ca);
}
if (num_merge_bases == 1)
@ -3889,6 +3908,7 @@ int merge_recursive_generic(struct merge_options *opt,
repo_hold_locked_index(opt->repo, &lock, LOCK_DIE_ON_ERROR);
clean = merge_recursive(opt, head_commit, next_commit, ca,
result);
free_commit_list(ca);
if (clean < 0) {
rollback_lock_file(&lock);
return clean;

View File

@ -104,7 +104,7 @@ int merge_trees(struct merge_options *opt,
int merge_recursive(struct merge_options *opt,
struct commit *h1,
struct commit *h2,
struct commit_list *merge_bases,
const struct commit_list *merge_bases,
struct commit **result);
/*
@ -123,7 +123,7 @@ int merge_recursive_generic(struct merge_options *opt,
const struct object_id *head,
const struct object_id *merge,
int num_merge_bases,
const struct object_id **merge_bases,
const struct object_id *merge_bases,
struct commit **result);
#endif

View File

@ -663,6 +663,7 @@ int notes_merge(struct notes_merge_options *o,
commit_list_insert(local, &parents);
create_notes_commit(o->repo, local_tree, parents, o->commit_msg.buf,
o->commit_msg.len, result_oid);
free_commit_list(parents);
}
found_result:

View File

@ -11,10 +11,11 @@
void create_notes_commit(struct repository *r,
struct notes_tree *t,
struct commit_list *parents,
const struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid)
{
struct commit_list *parents_to_free = NULL;
struct object_id tree_oid;
assert(t->initialized);
@ -29,7 +30,8 @@ void create_notes_commit(struct repository *r,
struct commit *parent = lookup_commit(r, &parent_oid);
if (repo_parse_commit(r, parent))
die("Failed to find/parse commit %s", t->ref);
commit_list_insert(parent, &parents);
commit_list_insert(parent, &parents_to_free);
parents = parents_to_free;
}
/* else: t->ref points to nothing, assume root/orphan commit */
}
@ -37,6 +39,8 @@ void create_notes_commit(struct repository *r,
if (commit_tree(msg, msg_len, &tree_oid, parents, result_oid, NULL,
NULL))
die("Failed to commit notes tree to database");
free_commit_list(parents_to_free);
}
void commit_notes(struct repository *r, struct notes_tree *t, const char *msg)
@ -189,6 +193,7 @@ void finish_copy_notes_for_rewrite(struct repository *r,
for (i = 0; c->trees[i]; i++) {
commit_notes(r, c->trees[i], msg);
free_notes(c->trees[i]);
free(c->trees[i]);
}
free(c->trees);
free(c);

View File

@ -20,7 +20,7 @@ struct repository;
*/
void create_notes_commit(struct repository *r,
struct notes_tree *t,
struct commit_list *parents,
const struct commit_list *parents,
const char *msg, size_t msg_len,
struct object_id *result_oid);

21
notes.c
View File

@ -1064,6 +1064,12 @@ void init_display_notes(struct display_notes_opt *opt)
{
memset(opt, 0, sizeof(*opt));
opt->use_default_notes = -1;
string_list_init_dup(&opt->extra_notes_refs);
}
void release_display_notes(struct display_notes_opt *opt)
{
string_list_clear(&opt->extra_notes_refs, 0);
}
void enable_default_display_notes(struct display_notes_opt *opt, int *show_notes)
@ -1077,19 +1083,15 @@ void enable_ref_display_notes(struct display_notes_opt *opt, int *show_notes,
struct strbuf buf = STRBUF_INIT;
strbuf_addstr(&buf, ref);
expand_notes_ref(&buf);
string_list_append(&opt->extra_notes_refs,
strbuf_detach(&buf, NULL));
string_list_append_nodup(&opt->extra_notes_refs,
strbuf_detach(&buf, NULL));
*show_notes = 1;
}
void disable_display_notes(struct display_notes_opt *opt, int *show_notes)
{
opt->use_default_notes = -1;
/* we have been strdup'ing ourselves, so trick
* string_list into free()ing strings */
opt->extra_notes_refs.strdup_strings = 1;
string_list_clear(&opt->extra_notes_refs, 0);
opt->extra_notes_refs.strdup_strings = 0;
*show_notes = 0;
}
@ -1221,11 +1223,16 @@ void prune_notes(struct notes_tree *t, int flags)
for_each_note(t, 0, prune_notes_helper, &l);
while (l) {
struct note_delete_list *next;
if (flags & NOTES_PRUNE_VERBOSE)
printf("%s\n", hash_to_hex(l->sha1));
if (!(flags & NOTES_PRUNE_DRYRUN))
remove_note(t, l->sha1);
l = l->next;
next = l->next;
free(l);
l = next;
}
}

View File

@ -275,6 +275,11 @@ struct display_notes_opt {
*/
void init_display_notes(struct display_notes_opt *opt);
/*
* Release resources acquired by the display_notes_opt.
*/
void release_display_notes(struct display_notes_opt *opt);
/*
* This family of functions enables or disables the display of notes. In
* particular, 'enable_default_display_notes' will display the default notes,

View File

@ -1759,6 +1759,11 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
return check_refname_format(sb->buf, 0);
}
void object_context_release(struct object_context *ctx)
{
free(ctx->path);
}
/*
* This is like "get_oid_basic()", except it allows "object ID expressions",
* notably "xyz^" for "parent of xyz"
@ -1766,7 +1771,9 @@ int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
int repo_get_oid(struct repository *r, const char *name, struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, 0, oid, &unused);
int ret = get_oid_with_context(r, name, 0, oid, &unused);
object_context_release(&unused);
return ret;
}
/*
@ -1804,8 +1811,10 @@ int repo_get_oid_committish(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, GET_OID_COMMITTISH,
oid, &unused);
int ret = get_oid_with_context(r, name, GET_OID_COMMITTISH,
oid, &unused);
object_context_release(&unused);
return ret;
}
int repo_get_oid_treeish(struct repository *r,
@ -1813,8 +1822,10 @@ int repo_get_oid_treeish(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, GET_OID_TREEISH,
oid, &unused);
int ret = get_oid_with_context(r, name, GET_OID_TREEISH,
oid, &unused);
object_context_release(&unused);
return ret;
}
int repo_get_oid_commit(struct repository *r,
@ -1822,8 +1833,10 @@ int repo_get_oid_commit(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, GET_OID_COMMIT,
oid, &unused);
int ret = get_oid_with_context(r, name, GET_OID_COMMIT,
oid, &unused);
object_context_release(&unused);
return ret;
}
int repo_get_oid_tree(struct repository *r,
@ -1831,8 +1844,10 @@ int repo_get_oid_tree(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, GET_OID_TREE,
oid, &unused);
int ret = get_oid_with_context(r, name, GET_OID_TREE,
oid, &unused);
object_context_release(&unused);
return ret;
}
int repo_get_oid_blob(struct repository *r,
@ -1840,8 +1855,10 @@ int repo_get_oid_blob(struct repository *r,
struct object_id *oid)
{
struct object_context unused;
return get_oid_with_context(r, name, GET_OID_BLOB,
oid, &unused);
int ret = get_oid_with_context(r, name, GET_OID_BLOB,
oid, &unused);
object_context_release(&unused);
return ret;
}
/* Must be called only when object_name:filename doesn't exist. */
@ -2119,6 +2136,7 @@ void maybe_die_on_misspelt_object_name(struct repository *r,
struct object_id oid;
get_oid_with_context_1(r, name, GET_OID_ONLY_TO_DIE | GET_OID_QUIETLY,
prefix, &oid, &oc);
object_context_release(&oc);
}
enum get_oid_result get_oid_with_context(struct repository *repo,

View File

@ -22,6 +22,8 @@ struct object_context {
char *path;
};
void object_context_release(struct object_context *ctx);
/*
* Return an abbreviated sha1 unique within this repository's object database.
* The result will be at least `len` characters long, and will be NUL

View File

@ -851,6 +851,8 @@ static int do_plain_rerere(struct repository *r,
if (update.nr)
update_paths(r, &update);
string_list_clear(&conflict, 0);
string_list_clear(&update, 0);
return write_rr(rr, fd);
}
@ -914,6 +916,7 @@ int repo_rerere(struct repository *r, int flags)
return 0;
status = do_plain_rerere(r, &merge_rr, fd);
free_rerere_dirs();
string_list_clear(&merge_rr, 1);
return status;
}

View File

@ -2151,30 +2151,26 @@ static int handle_dotdot(const char *arg,
struct rev_info *revs, int flags,
int cant_be_filename)
{
struct object_context a_oc, b_oc;
struct object_context a_oc = {0}, b_oc = {0};
char *dotdot = strstr(arg, "..");
int ret;
if (!dotdot)
return -1;
memset(&a_oc, 0, sizeof(a_oc));
memset(&b_oc, 0, sizeof(b_oc));
*dotdot = '\0';
ret = handle_dotdot_1(arg, dotdot, revs, flags, cant_be_filename,
&a_oc, &b_oc);
*dotdot = '.';
free(a_oc.path);
free(b_oc.path);
object_context_release(&a_oc);
object_context_release(&b_oc);
return ret;
}
static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int flags, unsigned revarg_opt)
{
struct object_context oc;
struct object_context oc = {0};
char *mark;
struct object *object;
struct object_id oid;
@ -2182,6 +2178,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
const char *arg = arg_;
int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME;
unsigned get_sha1_flags = GET_OID_RECORD_PATH;
int ret;
flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM;
@ -2190,17 +2187,22 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
* Just ".."? That is not a range but the
* pathspec for the parent directory.
*/
return -1;
ret = -1;
goto out;
}
if (!handle_dotdot(arg, revs, flags, revarg_opt))
return 0;
if (!handle_dotdot(arg, revs, flags, revarg_opt)) {
ret = 0;
goto out;
}
mark = strstr(arg, "^@");
if (mark && !mark[2]) {
*mark = 0;
if (add_parents_only(revs, arg, flags, 0))
return 0;
if (add_parents_only(revs, arg, flags, 0)) {
ret = 0;
goto out;
}
*mark = '^';
}
mark = strstr(arg, "^!");
@ -2215,8 +2217,10 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
if (mark[2]) {
if (strtol_i(mark + 2, 10, &exclude_parent) ||
exclude_parent < 1)
return -1;
exclude_parent < 1) {
ret = -1;
goto out;
}
}
*mark = 0;
@ -2238,17 +2242,25 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl
* should error out if we can't even get an oid, as
* `--missing=print` should be able to report missing oids.
*/
if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc))
return revs->ignore_missing ? 0 : -1;
if (get_oid_with_context(revs->repo, arg, get_sha1_flags, &oid, &oc)) {
ret = revs->ignore_missing ? 0 : -1;
goto out;
}
if (!cant_be_filename)
verify_non_filename(revs->prefix, arg);
object = get_reference(revs, arg, &oid, flags ^ local_flags);
if (!object)
return (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;
if (!object) {
ret = (revs->ignore_missing || revs->do_not_die_on_missing_objects) ? 0 : -1;
goto out;
}
add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags);
add_pending_object_with_path(revs, object, arg, oc.mode, oc.path);
free(oc.path);
return 0;
ret = 0;
out:
object_context_release(&oc);
return ret;
}
int handle_revision_arg(const char *arg, struct rev_info *revs, int flags, unsigned revarg_opt)
@ -3084,6 +3096,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
diagnose_missing_default(revs->def);
object = get_reference(revs, revs->def, &oid, 0);
add_pending_object_with_mode(revs, object, revs->def, oc.mode);
object_context_release(&oc);
}
/* Did the user ask for any diff output? Run the diff! */
@ -3190,6 +3203,7 @@ void release_revisions(struct rev_info *revs)
{
free_commit_list(revs->commits);
free_commit_list(revs->ancestry_path_bottoms);
release_display_notes(&revs->notes_opt);
object_array_clear(&revs->pending);
object_array_clear(&revs->boundary_commits);
release_revisions_cmdline(&revs->cmdline);
@ -3199,7 +3213,7 @@ void release_revisions(struct rev_info *revs)
release_revisions_mailmap(revs->mailmap);
free_grep_patterns(&revs->grep_filter);
graph_clear(revs->graph);
/* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */
diff_free(&revs->diffopt);
diff_free(&revs->pruning);
reflog_walk_info_release(revs->reflog_info);
release_revisions_topo_walk_info(revs->topo_walk_info);
@ -4452,6 +4466,7 @@ struct commit *get_revision(struct rev_info *revs)
reversed = NULL;
while ((c = get_revision_internal(revs)))
commit_list_insert(c, &reversed);
free_commit_list(revs->commits);
revs->commits = reversed;
revs->reverse = 0;
revs->reverse_output_stage = 1;

View File

@ -1713,6 +1713,7 @@ static int try_to_commit(struct repository *r,
out:
free_commit_extra_headers(extra);
free_commit_list(parents);
strbuf_release(&err);
strbuf_release(&commit_msg);
free(amend_author);
@ -4376,6 +4377,7 @@ leave_merge:
strbuf_release(&ref_name);
rollback_lock_file(&lock);
free_commit_list(to_merge);
free_commit_list(bases);
return ret;
}
@ -5207,33 +5209,47 @@ static int commit_staged_changes(struct repository *r,
struct replay_ctx *ctx = opts->ctx;
unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
unsigned int final_fixup = 0, is_clean;
struct strbuf rev = STRBUF_INIT;
int ret;
if (has_unstaged_changes(r, 1))
return error(_("cannot rebase: You have unstaged changes."));
if (has_unstaged_changes(r, 1)) {
ret = error(_("cannot rebase: You have unstaged changes."));
goto out;
}
is_clean = !has_uncommitted_changes(r, 0);
if (!is_clean && !file_exists(rebase_path_message())) {
const char *gpg_opt = gpg_sign_opt_quoted(opts);
return error(_(staged_changes_advice), gpg_opt, gpg_opt);
ret = error(_(staged_changes_advice), gpg_opt, gpg_opt);
goto out;
}
if (file_exists(rebase_path_amend())) {
struct strbuf rev = STRBUF_INIT;
struct object_id head, to_amend;
if (repo_get_oid(r, "HEAD", &head))
return error(_("cannot amend non-existing commit"));
if (!read_oneliner(&rev, rebase_path_amend(), 0))
return error(_("invalid file: '%s'"), rebase_path_amend());
if (get_oid_hex(rev.buf, &to_amend))
return error(_("invalid contents: '%s'"),
rebase_path_amend());
if (!is_clean && !oideq(&head, &to_amend))
return error(_("\nYou have uncommitted changes in your "
"working tree. Please, commit them\n"
"first and then run 'git rebase "
"--continue' again."));
if (repo_get_oid(r, "HEAD", &head)) {
ret = error(_("cannot amend non-existing commit"));
goto out;
}
if (!read_oneliner(&rev, rebase_path_amend(), 0)) {
ret = error(_("invalid file: '%s'"), rebase_path_amend());
goto out;
}
if (get_oid_hex(rev.buf, &to_amend)) {
ret = error(_("invalid contents: '%s'"),
rebase_path_amend());
goto out;
}
if (!is_clean && !oideq(&head, &to_amend)) {
ret = error(_("\nYou have uncommitted changes in your "
"working tree. Please, commit them\n"
"first and then run 'git rebase "
"--continue' again."));
goto out;
}
/*
* When skipping a failed fixup/squash, we need to edit the
* commit message, the current fixup list and count, and if it
@ -5265,9 +5281,11 @@ static int commit_staged_changes(struct repository *r,
len--;
strbuf_setlen(&ctx->current_fixups, len);
if (write_message(p, len, rebase_path_current_fixups(),
0) < 0)
return error(_("could not write file: '%s'"),
rebase_path_current_fixups());
0) < 0) {
ret = error(_("could not write file: '%s'"),
rebase_path_current_fixups());
goto out;
}
/*
* If a fixup/squash in a fixup/squash chain failed, the
@ -5297,35 +5315,38 @@ static int commit_staged_changes(struct repository *r,
* We need to update the squash message to skip
* the latest commit message.
*/
int res = 0;
struct commit *commit;
const char *msg;
const char *path = rebase_path_squash_msg();
const char *encoding = get_commit_output_encoding();
if (parse_head(r, &commit))
return error(_("could not parse HEAD"));
if (parse_head(r, &commit)) {
ret = error(_("could not parse HEAD"));
goto out;
}
p = repo_logmsg_reencode(r, commit, NULL, encoding);
if (!p) {
res = error(_("could not parse commit %s"),
ret = error(_("could not parse commit %s"),
oid_to_hex(&commit->object.oid));
goto unuse_commit_buffer;
}
find_commit_subject(p, &msg);
if (write_message(msg, strlen(msg), path, 0)) {
res = error(_("could not write file: "
ret = error(_("could not write file: "
"'%s'"), path);
goto unuse_commit_buffer;
}
ret = 0;
unuse_commit_buffer:
repo_unuse_commit_buffer(r, commit, p);
if (res)
return res;
if (ret)
goto out;
}
}
strbuf_release(&rev);
flags |= AMEND_MSG;
}
@ -5333,18 +5354,29 @@ static int commit_staged_changes(struct repository *r,
if (refs_ref_exists(get_main_ref_store(r),
"CHERRY_PICK_HEAD") &&
refs_delete_ref(get_main_ref_store(r), "",
"CHERRY_PICK_HEAD", NULL, REF_NO_DEREF))
return error(_("could not remove CHERRY_PICK_HEAD"));
if (unlink(git_path_merge_msg(r)) && errno != ENOENT)
return error_errno(_("could not remove '%s'"),
git_path_merge_msg(r));
if (!final_fixup)
return 0;
"CHERRY_PICK_HEAD", NULL, REF_NO_DEREF)) {
ret = error(_("could not remove CHERRY_PICK_HEAD"));
goto out;
}
if (unlink(git_path_merge_msg(r)) && errno != ENOENT) {
ret = error_errno(_("could not remove '%s'"),
git_path_merge_msg(r));
goto out;
}
if (!final_fixup) {
ret = 0;
goto out;
}
}
if (run_git_commit(final_fixup ? NULL : rebase_path_message(),
opts, flags))
return error(_("could not commit staged changes."));
opts, flags)) {
ret = error(_("could not commit staged changes."));
goto out;
}
unlink(rebase_path_amend());
unlink(git_path_merge_head(r));
refs_delete_ref(get_main_ref_store(r), "", "AUTO_MERGE",
@ -5362,7 +5394,12 @@ static int commit_staged_changes(struct repository *r,
strbuf_reset(&ctx->current_fixups);
ctx->current_fixup_count = 0;
}
return 0;
ret = 0;
out:
strbuf_release(&rev);
return ret;
}
int sequencer_continue(struct repository *r, struct replay_opts *opts)
@ -5978,6 +6015,9 @@ static int make_script_with_merges(struct pretty_print_context *pp,
strbuf_release(&oneline);
strbuf_release(&buf);
oidset_clear(&interesting);
oidset_clear(&child_seen);
oidset_clear(&shown);
oidmap_free(&commit2todo, 1);
oidmap_free(&state.commit2label, 1);
hashmap_clear_and_free(&state.labels, struct labels_entry, entry);

View File

@ -207,6 +207,7 @@ int cmd__parse_options(int argc, const char **argv)
expect.strdup_strings = 1;
string_list_clear(&expect, 0);
string_list_clear(&list, 0);
free(file);
return ret;
}

View File

@ -5,6 +5,7 @@ test_description='read-tree -m -u checks working tree files'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-read-tree.sh

View File

@ -1,6 +1,8 @@
#!/bin/sh
test_description='Test various callers of read_index_unmerged'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup modify/delete + directory/file conflict' '

View File

@ -4,6 +4,7 @@ test_description='rerere run in a workdir'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success SYMLINKS setup '

View File

@ -23,6 +23,7 @@ one tagged as v1.0.0. They all have one regular file each.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_cmp_failed_rev_parse () {

View File

@ -2,6 +2,7 @@
test_description='Test handling of overwriting untracked files'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_setup_reset () {

View File

@ -5,6 +5,7 @@
test_description='Test commit notes'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
write_script fake_editor <<\EOF

View File

@ -2,6 +2,7 @@
test_description='Test git notes prune'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup: create a few commits with notes' '

View File

@ -5,6 +5,7 @@
test_description='Test merging of notes trees'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@
test_description='Test notes merging with auto-resolving strategies'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Set up a notes merge scenario with all kinds of potential conflicts

View File

@ -11,6 +11,7 @@ among other things.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_AUTHOR_NAME=author@name

View File

@ -2,6 +2,7 @@
test_description='git rebase + directory rename tests'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh

View File

@ -8,6 +8,7 @@ test_description='git rebase --merge --skip tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh

View File

@ -5,6 +5,7 @@ test_description='messages from rebase operation'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -5,6 +5,7 @@ test_description='git rebase --abort tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='git rebase --whitespace=fix
This test runs git rebase --whitespace=fix and make sure that it works.
'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# prepare initial revision of "file" with a blank line at the end

View File

@ -5,6 +5,7 @@ test_description='git rebase --continue tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh

View File

@ -7,6 +7,7 @@ test_description='git rebase --autostash tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -1,6 +1,8 @@
#!/bin/sh
test_description='basic rebase topology tests'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh

View File

@ -2,6 +2,7 @@
test_description='git rebase of commits that start or become empty'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup test repository' '

View File

@ -5,6 +5,7 @@ test_description='git rebase --signoff
This test runs git rebase --signoff and make sure that it works.
'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh

View File

@ -21,6 +21,7 @@ Initial setup:
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-rebase.sh
. "$TEST_DIRECTORY"/lib-log-graph.sh

View File

@ -17,6 +17,7 @@ Initial setup:
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
compare_msg () {

View File

@ -11,6 +11,7 @@ checks that git cherry only returns the second patch in the local branch
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
GIT_AUTHOR_EMAIL=bogus_email_address

View File

@ -5,6 +5,7 @@ test_description='cherry-pick should rerere for conflicts'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='test cherry-picking an empty commit'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='test cherry-picking many commits'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check_head_differs_from() {

View File

@ -4,6 +4,7 @@ test_description='Test cherry-pick with directory/file conflicts'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'Initialize repository' '

View File

@ -2,6 +2,7 @@
test_description='Test git stash show configuration.'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -6,6 +6,7 @@ test_description='Test diff indent heuristic.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-diff.sh

View File

@ -5,6 +5,7 @@
test_description='git apply --build-fake-ancestor handling.'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -2,6 +2,7 @@
test_description='am --abort'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -2,6 +2,7 @@
test_description='git-am command-line options override saved options'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
format_patch () {

View File

@ -5,6 +5,7 @@ test_description='magic pathspec tests using git-log'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -9,6 +9,7 @@ test_description='git-am mbox with dos line ending.
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# Three patches which will be added as files with dos line ending.

View File

@ -2,6 +2,7 @@
test_description='git am handling submodules'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-submodule-update.sh

View File

@ -5,6 +5,7 @@ test_description='Test workflows involving pull request.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
if ! test_have_prereq PERL

View File

@ -3,9 +3,9 @@
# Copyright (c) 2005 Junio C Hamano
#
test_description='git pack-object
test_description='git pack-object'
'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -4,6 +4,7 @@ test_description='git pack-object --include-tag'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
TRASH=$(pwd)

View File

@ -7,6 +7,7 @@ test_description='Test the post-rewrite hook.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -4,6 +4,7 @@ test_description='test local clone'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
repo_is_hardlinked() {

View File

@ -4,6 +4,7 @@ test_description='some bundle related tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -4,6 +4,7 @@ test_description='test refspec written by clone-command'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup' '

View File

@ -5,6 +5,7 @@ test_description='miscellaneous rev-list tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='Revision traversal vs grafts and path limiter'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='--reverse combines with --parents'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh

View File

@ -8,6 +8,7 @@ test_description='log family learns --stdin'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
check () {

View File

@ -8,6 +8,7 @@ test_description='Test git-bundle'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-bundle.sh
. "$TEST_DIRECTORY"/lib-terminal.sh

Some files were not shown because too many files have changed in this diff Show More