run_hooks("post-applypatch");
+ free_commit_list(parents);
strbuf_release(&sb);
}
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
+ int ret;
git_config(git_default_config, NULL);
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;
}
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)) {
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);
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,
&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;
}
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;
}
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,
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;
}
goto done;
}
+ free_commit_list(parents);
+ parents = NULL;
+
if (include_untracked) {
if (save_untracked_files(info, &msg, untracked_files)) {
if (!quiet)
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),
strbuf_release(&commit_tree_label);
strbuf_release(&msg);
strbuf_release(&untracked_files);
+ free_commit_list(parents);
return ret;
}
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;
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;
}
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)
}
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;
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;
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;
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)) {
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);
}
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 **);
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);
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:
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);
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 */
}
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)
*/
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);
out:
free_commit_extra_headers(extra);
+ free_commit_list(parents);
strbuf_release(&err);
strbuf_release(&commit_msg);
free(amend_author);
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_description='git rebase of commits that start or become empty'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'setup test repository' '
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 '
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 'set up commits for rebasing' '