mirror of
https://github.com/git/git.git
synced 2024-11-26 19:43:32 +08:00
Merge branch 'ps/leakfixes-part-8'
More leakfixes. * ps/leakfixes-part-8: (23 commits) builtin/send-pack: fix leaking list of push options remote: fix leaking push reports t/helper: fix leaks in proc-receive helper pack-write: fix return parameter of `write_rev_file_order()` revision: fix leaking saved parents revision: fix memory leaks when rewriting parents midx-write: fix leaking buffer pack-bitmap-write: fix leaking OID array pseudo-merge: fix leaking strmap keys pseudo-merge: fix various memory leaks line-log: fix several memory leaks diff: improve lifecycle management of diff queues builtin/revert: fix leaking `gpg_sign` and `strategy` config t/helper: fix leaking repository in partial-clone helper builtin/clone: fix leaking repo state when cloning with bundle URIs builtin/pack-redundant: fix various memory leaks builtin/stash: fix leaking `pathspec_from_file` submodule: fix leaking submodule entry list wt-status: fix leaking buffer with sparse directories shell: fix leaking strings ...
This commit is contained in:
commit
31bc4454de
8
bloom.c
8
bloom.c
@ -476,8 +476,6 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
|
||||
*last_slash = '\0';
|
||||
|
||||
} while (*path);
|
||||
|
||||
diff_free_filepair(diff_queued_diff.queue[i]);
|
||||
}
|
||||
|
||||
if (hashmap_get_size(&pathmap) > settings->max_changed_paths) {
|
||||
@ -508,8 +506,6 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
|
||||
cleanup:
|
||||
hashmap_clear_and_free(&pathmap, struct pathmap_hash_entry, entry);
|
||||
} else {
|
||||
for (i = 0; i < diff_queued_diff.nr; i++)
|
||||
diff_free_filepair(diff_queued_diff.queue[i]);
|
||||
init_truncated_large_filter(filter, settings->hash_version);
|
||||
|
||||
if (computed)
|
||||
@ -519,9 +515,7 @@ struct bloom_filter *get_or_compute_bloom_filter(struct repository *r,
|
||||
if (computed)
|
||||
*computed |= BLOOM_COMPUTED;
|
||||
|
||||
free(diff_queued_diff.queue);
|
||||
DIFF_QUEUE_CLEAR(&diff_queued_diff);
|
||||
|
||||
diff_queue_clear(&diff_queued_diff);
|
||||
return filter;
|
||||
}
|
||||
|
||||
|
8
branch.c
8
branch.c
@ -738,6 +738,7 @@ static int submodule_create_branch(struct repository *r,
|
||||
|
||||
strbuf_release(&child_err);
|
||||
strbuf_release(&out_buf);
|
||||
free(out_prefix);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -794,7 +795,7 @@ void create_branches_recursively(struct repository *r, const char *name,
|
||||
create_branch(r, name, start_committish, force, 0, reflog, quiet,
|
||||
BRANCH_TRACK_NEVER, dry_run);
|
||||
if (dry_run)
|
||||
return;
|
||||
goto out;
|
||||
/*
|
||||
* NEEDSWORK If tracking was set up in the superproject but not the
|
||||
* submodule, users might expect "git branch --recurse-submodules" to
|
||||
@ -815,8 +816,11 @@ void create_branches_recursively(struct repository *r, const char *name,
|
||||
die(_("submodule '%s': cannot create branch '%s'"),
|
||||
submodule_entry_list.entries[i].submodule->name,
|
||||
name);
|
||||
repo_clear(submodule_entry_list.entries[i].repo);
|
||||
}
|
||||
|
||||
out:
|
||||
submodule_entry_list_release(&submodule_entry_list);
|
||||
free(branch_point);
|
||||
}
|
||||
|
||||
void remove_merge_branch_state(struct repository *r)
|
||||
|
@ -15,13 +15,23 @@ int cmd_annotate(int argc,
|
||||
struct repository *repo UNUSED)
|
||||
{
|
||||
struct strvec args = STRVEC_INIT;
|
||||
int i;
|
||||
const char **args_copy;
|
||||
int ret;
|
||||
|
||||
strvec_pushl(&args, "annotate", "-c", NULL);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
for (int i = 1; i < argc; i++)
|
||||
strvec_push(&args, argv[i]);
|
||||
}
|
||||
|
||||
return cmd_blame(args.nr, args.v, prefix, the_repository);
|
||||
/*
|
||||
* `cmd_blame()` ends up modifying the array, which causes memory leaks
|
||||
* if we didn't copy the array here.
|
||||
*/
|
||||
CALLOC_ARRAY(args_copy, args.nr + 1);
|
||||
COPY_ARRAY(args_copy, args.v, args.nr);
|
||||
|
||||
ret = cmd_blame(args.nr, args_copy, prefix, the_repository);
|
||||
|
||||
strvec_clear(&args);
|
||||
free(args_copy);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1403,8 +1403,17 @@ int cmd_clone(int argc,
|
||||
* data from the --bundle-uri option.
|
||||
*/
|
||||
if (bundle_uri) {
|
||||
struct remote_state *state;
|
||||
int has_heuristic = 0;
|
||||
|
||||
/*
|
||||
* We need to save the remote state as our remote's lifetime is
|
||||
* tied to it.
|
||||
*/
|
||||
state = the_repository->remote_state;
|
||||
the_repository->remote_state = NULL;
|
||||
repo_clear(the_repository);
|
||||
|
||||
/* At this point, we need the_repository to match the cloned repo. */
|
||||
if (repo_init(the_repository, git_dir, work_tree))
|
||||
warning(_("failed to initialize the repo, skipping bundle URI"));
|
||||
@ -1413,6 +1422,10 @@ int cmd_clone(int argc,
|
||||
bundle_uri);
|
||||
else if (has_heuristic)
|
||||
git_config_set_gently("fetch.bundleuri", bundle_uri);
|
||||
|
||||
remote_state_clear(the_repository->remote_state);
|
||||
free(the_repository->remote_state);
|
||||
the_repository->remote_state = state;
|
||||
} else {
|
||||
/*
|
||||
* Populate transport->got_remote_bundle_uri and
|
||||
@ -1422,12 +1435,26 @@ int cmd_clone(int argc,
|
||||
|
||||
if (transport->bundles &&
|
||||
hashmap_get_size(&transport->bundles->bundles)) {
|
||||
struct remote_state *state;
|
||||
|
||||
/*
|
||||
* We need to save the remote state as our remote's
|
||||
* lifetime is tied to it.
|
||||
*/
|
||||
state = the_repository->remote_state;
|
||||
the_repository->remote_state = NULL;
|
||||
repo_clear(the_repository);
|
||||
|
||||
/* At this point, we need the_repository to match the cloned repo. */
|
||||
if (repo_init(the_repository, git_dir, work_tree))
|
||||
warning(_("failed to initialize the repo, skipping bundle URI"));
|
||||
else if (fetch_bundle_list(the_repository,
|
||||
transport->bundles))
|
||||
warning(_("failed to fetch advertised bundles"));
|
||||
|
||||
remote_state_clear(the_repository->remote_state);
|
||||
free(the_repository->remote_state);
|
||||
the_repository->remote_state = state;
|
||||
} else {
|
||||
clear_bundle_list(transport->bundles);
|
||||
FREE_AND_NULL(transport->bundles);
|
||||
|
@ -1505,7 +1505,7 @@ static void rename_tmp_packfile(const char **final_name,
|
||||
struct strbuf *name, unsigned char *hash,
|
||||
const char *ext, int make_read_only_if_same)
|
||||
{
|
||||
if (*final_name != curr_name) {
|
||||
if (!*final_name || strcmp(*final_name, curr_name)) {
|
||||
if (!*final_name)
|
||||
*final_name = odb_pack_name(name, hash, ext);
|
||||
if (finalize_object_file(curr_name, *final_name))
|
||||
@ -1726,7 +1726,7 @@ int cmd_index_pack(int argc,
|
||||
{
|
||||
int i, fix_thin_pack = 0, verify = 0, stat_only = 0, rev_index;
|
||||
const char *curr_index;
|
||||
const char *curr_rev_index = NULL;
|
||||
char *curr_rev_index = NULL;
|
||||
const char *index_name = NULL, *pack_name = NULL, *rev_index_name = NULL;
|
||||
const char *keep_msg = NULL;
|
||||
const char *promisor_msg = NULL;
|
||||
@ -1968,8 +1968,7 @@ int cmd_index_pack(int argc,
|
||||
free((void *) curr_pack);
|
||||
if (!index_name)
|
||||
free((void *) curr_index);
|
||||
if (!rev_index_name)
|
||||
free((void *) curr_rev_index);
|
||||
free(curr_rev_index);
|
||||
|
||||
/*
|
||||
* Let the caller know this pack is not self contained
|
||||
|
@ -69,6 +69,15 @@ static inline void llist_init(struct llist **list)
|
||||
(*list)->size = 0;
|
||||
}
|
||||
|
||||
static void llist_free(struct llist *list)
|
||||
{
|
||||
for (struct llist_item *i = list->front, *next; i; i = next) {
|
||||
next = i->next;
|
||||
llist_item_put(i);
|
||||
}
|
||||
free(list);
|
||||
}
|
||||
|
||||
static struct llist * llist_copy(struct llist *list)
|
||||
{
|
||||
struct llist *ret;
|
||||
@ -206,6 +215,14 @@ static inline struct pack_list * pack_list_insert(struct pack_list **pl,
|
||||
return p;
|
||||
}
|
||||
|
||||
static void pack_list_free(struct pack_list *pl)
|
||||
{
|
||||
for (struct pack_list *next; pl; pl = next) {
|
||||
next = pl->next;
|
||||
free(pl);
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t pack_list_size(struct pack_list *pl)
|
||||
{
|
||||
size_t ret = 0;
|
||||
@ -419,7 +436,8 @@ static void minimize(struct pack_list **min)
|
||||
|
||||
/* return if there are no objects missing from the unique set */
|
||||
if (missing->size == 0) {
|
||||
free(missing);
|
||||
llist_free(missing);
|
||||
pack_list_free(non_unique);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -434,6 +452,8 @@ static void minimize(struct pack_list **min)
|
||||
}
|
||||
|
||||
while (non_unique) {
|
||||
struct pack_list *next;
|
||||
|
||||
/* sort the non_unique packs, greater size of remaining_objects first */
|
||||
sort_pack_list(&non_unique);
|
||||
if (non_unique->remaining_objects->size == 0)
|
||||
@ -444,8 +464,14 @@ static void minimize(struct pack_list **min)
|
||||
for (pl = non_unique->next; pl && pl->remaining_objects->size > 0; pl = pl->next)
|
||||
llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects);
|
||||
|
||||
non_unique = non_unique->next;
|
||||
next = non_unique->next;
|
||||
free(non_unique);
|
||||
non_unique = next;
|
||||
}
|
||||
|
||||
pack_list_free(non_unique);
|
||||
llist_free(unique_pack_objects);
|
||||
llist_free(missing);
|
||||
}
|
||||
|
||||
static void load_all_objects(void)
|
||||
@ -565,7 +591,6 @@ static void load_all(void)
|
||||
int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, struct repository *repo UNUSED) {
|
||||
int i; int i_still_use_this = 0; struct pack_list *min = NULL, *red, *pl;
|
||||
struct llist *ignore;
|
||||
struct object_id *oid;
|
||||
char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */
|
||||
|
||||
if (argc == 2 && !strcmp(argv[1], "-h"))
|
||||
@ -625,11 +650,11 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
|
||||
/* ignore objects given on stdin */
|
||||
llist_init(&ignore);
|
||||
if (!isatty(0)) {
|
||||
struct object_id oid;
|
||||
while (fgets(buf, sizeof(buf), stdin)) {
|
||||
oid = xmalloc(sizeof(*oid));
|
||||
if (get_oid_hex(buf, oid))
|
||||
if (get_oid_hex(buf, &oid))
|
||||
die("Bad object ID on stdin: %s", buf);
|
||||
llist_insert_sorted_unique(ignore, oid, NULL);
|
||||
llist_insert_sorted_unique(ignore, &oid, NULL);
|
||||
}
|
||||
}
|
||||
llist_sorted_difference_inplace(all_objects, ignore);
|
||||
@ -671,5 +696,8 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix UNUSED, s
|
||||
fprintf(stderr, "%luMB of redundant packs in total.\n",
|
||||
(unsigned long)pack_set_bytecount(red)/(1024*1024));
|
||||
|
||||
pack_list_free(red);
|
||||
pack_list_free(min);
|
||||
llist_free(ignore);
|
||||
return 0;
|
||||
}
|
||||
|
@ -374,6 +374,7 @@ static void write_head_info(void)
|
||||
struct command {
|
||||
struct command *next;
|
||||
const char *error_string;
|
||||
char *error_string_owned;
|
||||
struct ref_push_report *report;
|
||||
unsigned int skip_update:1,
|
||||
did_not_exist:1,
|
||||
@ -1083,7 +1084,7 @@ static int read_proc_receive_report(struct packet_reader *reader,
|
||||
hint->run_proc_receive |= RUN_PROC_RECEIVE_RETURNED;
|
||||
if (!strcmp(head, "ng")) {
|
||||
if (p)
|
||||
hint->error_string = xstrdup(p);
|
||||
hint->error_string = hint->error_string_owned = xstrdup(p);
|
||||
else
|
||||
hint->error_string = "failed";
|
||||
code = -1;
|
||||
@ -2054,6 +2055,8 @@ static void free_commands(struct command *commands)
|
||||
while (commands) {
|
||||
struct command *next = commands->next;
|
||||
|
||||
ref_push_report_free(commands->report);
|
||||
free(commands->error_string_owned);
|
||||
free(commands);
|
||||
commands = next;
|
||||
}
|
||||
|
@ -110,6 +110,9 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
|
||||
const char * const * usage_str = revert_or_cherry_pick_usage(opts);
|
||||
const char *me = action_name(opts);
|
||||
const char *cleanup_arg = NULL;
|
||||
const char sentinel_value;
|
||||
const char *strategy = &sentinel_value;
|
||||
const char *gpg_sign = &sentinel_value;
|
||||
enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED;
|
||||
int cmd = 0;
|
||||
struct option base_options[] = {
|
||||
@ -125,10 +128,10 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
|
||||
OPT_CALLBACK('m', "mainline", opts, N_("parent-number"),
|
||||
N_("select mainline parent"), option_parse_m),
|
||||
OPT_RERERE_AUTOUPDATE(&opts->allow_rerere_auto),
|
||||
OPT_STRING(0, "strategy", &opts->strategy, N_("strategy"), N_("merge strategy")),
|
||||
OPT_STRING(0, "strategy", &strategy, N_("strategy"), N_("merge strategy")),
|
||||
OPT_STRVEC('X', "strategy-option", &opts->xopts, N_("option"),
|
||||
N_("option for merge strategy")),
|
||||
{ OPTION_STRING, 'S', "gpg-sign", &opts->gpg_sign, N_("key-id"),
|
||||
{ OPTION_STRING, 'S', "gpg-sign", &gpg_sign, N_("key-id"),
|
||||
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
|
||||
OPT_END()
|
||||
};
|
||||
@ -240,8 +243,14 @@ static int run_sequencer(int argc, const char **argv, const char *prefix,
|
||||
usage_with_options(usage_str, options);
|
||||
|
||||
/* These option values will be free()d */
|
||||
opts->gpg_sign = xstrdup_or_null(opts->gpg_sign);
|
||||
opts->strategy = xstrdup_or_null(opts->strategy);
|
||||
if (gpg_sign != &sentinel_value) {
|
||||
free(opts->gpg_sign);
|
||||
opts->gpg_sign = xstrdup_or_null(gpg_sign);
|
||||
}
|
||||
if (strategy != &sentinel_value) {
|
||||
free(opts->strategy);
|
||||
opts->strategy = xstrdup_or_null(strategy);
|
||||
}
|
||||
if (!opts->strategy && getenv("GIT_TEST_MERGE_ALGORITHM"))
|
||||
opts->strategy = xstrdup(getenv("GIT_TEST_MERGE_ALGORITHM"));
|
||||
free(options);
|
||||
|
@ -340,6 +340,7 @@ int cmd_send_pack(int argc,
|
||||
/* stable plumbing output; do not modify or localize */
|
||||
fprintf(stderr, "Everything up-to-date\n");
|
||||
|
||||
string_list_clear(&push_options, 0);
|
||||
free_refs(remote_refs);
|
||||
free_refs(local_refs);
|
||||
refspec_clear(&rs);
|
||||
|
@ -1759,7 +1759,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
|
||||
int quiet = 0;
|
||||
int pathspec_file_nul = 0;
|
||||
const char *stash_msg = NULL;
|
||||
const char *pathspec_from_file = NULL;
|
||||
char *pathspec_from_file = NULL;
|
||||
struct pathspec ps;
|
||||
struct option options[] = {
|
||||
OPT_BOOL('k', "keep-index", &keep_index,
|
||||
@ -1821,7 +1821,9 @@ static int push_stash(int argc, const char **argv, const char *prefix,
|
||||
|
||||
ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
|
||||
include_untracked, only_staged);
|
||||
|
||||
clear_pathspec(&ps);
|
||||
free(pathspec_from_file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
22
diff.c
22
diff.c
@ -5983,11 +5983,18 @@ void diff_free_filepair(struct diff_filepair *p)
|
||||
free(p);
|
||||
}
|
||||
|
||||
void diff_free_queue(struct diff_queue_struct *q)
|
||||
void diff_queue_init(struct diff_queue_struct *q)
|
||||
{
|
||||
struct diff_queue_struct blank = DIFF_QUEUE_INIT;
|
||||
memcpy(q, &blank, sizeof(*q));
|
||||
}
|
||||
|
||||
void diff_queue_clear(struct diff_queue_struct *q)
|
||||
{
|
||||
for (int i = 0; i < q->nr; i++)
|
||||
diff_free_filepair(q->queue[i]);
|
||||
free(q->queue);
|
||||
diff_queue_init(q);
|
||||
}
|
||||
|
||||
const char *diff_aligned_abbrev(const struct object_id *oid, int len)
|
||||
@ -6551,8 +6558,7 @@ int diff_flush_patch_id(struct diff_options *options, struct object_id *oid, int
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
int result = diff_get_patch_id(options, oid, diff_header_only);
|
||||
|
||||
diff_free_queue(q);
|
||||
DIFF_QUEUE_CLEAR(q);
|
||||
diff_queue_clear(q);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -6835,8 +6841,7 @@ void diff_flush(struct diff_options *options)
|
||||
}
|
||||
|
||||
free_queue:
|
||||
diff_free_queue(q);
|
||||
DIFF_QUEUE_CLEAR(q);
|
||||
diff_queue_clear(q);
|
||||
diff_free(options);
|
||||
|
||||
/*
|
||||
@ -6867,9 +6872,7 @@ static void diffcore_apply_filter(struct diff_options *options)
|
||||
{
|
||||
int i;
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
|
||||
if (!options->filter)
|
||||
return;
|
||||
@ -6962,8 +6965,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
|
||||
{
|
||||
int i;
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
|
@ -131,7 +131,7 @@ static int should_break(struct repository *r,
|
||||
void diffcore_break(struct repository *r, int break_score)
|
||||
{
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
|
||||
/* When the filepair has this much edit (insert and delete),
|
||||
* it is first considered to be a rewrite and broken into a
|
||||
@ -178,8 +178,6 @@ void diffcore_break(struct repository *r, int break_score)
|
||||
if (!merge_score)
|
||||
merge_score = DEFAULT_MERGE_SCORE;
|
||||
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
int score;
|
||||
@ -275,11 +273,9 @@ static void merge_broken(struct diff_filepair *p,
|
||||
void diffcore_merge_broken(void)
|
||||
{
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
int i, j;
|
||||
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
if (!p)
|
||||
|
@ -182,9 +182,7 @@ static void pickaxe(struct diff_queue_struct *q, struct diff_options *o,
|
||||
regex_t *regexp, kwset_t kws, pickaxe_fn fn)
|
||||
{
|
||||
int i;
|
||||
struct diff_queue_struct outq;
|
||||
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
|
||||
if (o->pickaxe_opts & DIFF_PICKAXE_ALL) {
|
||||
/* Showing the whole changeset if needle exists */
|
||||
|
@ -1388,7 +1388,7 @@ void diffcore_rename_extended(struct diff_options *options,
|
||||
int detect_rename = options->detect_rename;
|
||||
int minimum_score = options->rename_score;
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
struct diff_score *mx;
|
||||
int i, j, rename_count, skip_unmodified = 0;
|
||||
int num_destinations, dst_cnt;
|
||||
@ -1638,7 +1638,6 @@ void diffcore_rename_extended(struct diff_options *options,
|
||||
* are recorded in rename_dst. The original list is still in *q.
|
||||
*/
|
||||
trace2_region_enter("diff", "write back to queue", options->repo);
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
struct diff_filepair *pair_to_free = NULL;
|
||||
|
@ -10,7 +10,7 @@
|
||||
void diffcore_rotate(struct diff_options *opt)
|
||||
{
|
||||
struct diff_queue_struct *q = &diff_queued_diff;
|
||||
struct diff_queue_struct outq;
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
int rotate_to, i;
|
||||
|
||||
if (!q->nr)
|
||||
@ -31,7 +31,6 @@ void diffcore_rotate(struct diff_options *opt)
|
||||
return;
|
||||
}
|
||||
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
rotate_to = i;
|
||||
|
||||
for (i = rotate_to; i < q->nr; i++)
|
||||
|
10
diffcore.h
10
diffcore.h
@ -153,18 +153,16 @@ struct diff_queue_struct {
|
||||
int nr;
|
||||
};
|
||||
|
||||
#define DIFF_QUEUE_CLEAR(q) \
|
||||
do { \
|
||||
(q)->queue = NULL; \
|
||||
(q)->nr = (q)->alloc = 0; \
|
||||
} while (0)
|
||||
#define DIFF_QUEUE_INIT { 0 }
|
||||
|
||||
void diff_queue_init(struct diff_queue_struct *q);
|
||||
void diff_queue_clear(struct diff_queue_struct *q);
|
||||
|
||||
extern struct diff_queue_struct diff_queued_diff;
|
||||
struct diff_filepair *diff_queue(struct diff_queue_struct *,
|
||||
struct diff_filespec *,
|
||||
struct diff_filespec *);
|
||||
void diff_q(struct diff_queue_struct *, struct diff_filepair *);
|
||||
void diff_free_queue(struct diff_queue_struct *q);
|
||||
|
||||
/* dir_rename_relevance: the reason we want rename information for a dir */
|
||||
enum dir_rename_relevance {
|
||||
|
69
line-log.c
69
line-log.c
@ -248,8 +248,10 @@ static void line_log_data_init(struct line_log_data *r)
|
||||
static void line_log_data_clear(struct line_log_data *r)
|
||||
{
|
||||
range_set_release(&r->ranges);
|
||||
free(r->path);
|
||||
if (r->pair)
|
||||
diff_free_filepair(r->pair);
|
||||
diff_ranges_release(&r->diff);
|
||||
}
|
||||
|
||||
static void free_line_log_data(struct line_log_data *r)
|
||||
@ -571,7 +573,8 @@ parse_lines(struct repository *r, struct commit *commit,
|
||||
struct line_log_data *p;
|
||||
|
||||
for_each_string_list_item(item, args) {
|
||||
const char *name_part, *range_part;
|
||||
const char *name_part;
|
||||
char *range_part;
|
||||
char *full_name;
|
||||
struct diff_filespec *spec;
|
||||
long begin = 0, end = 0;
|
||||
@ -615,6 +618,7 @@ parse_lines(struct repository *r, struct commit *commit,
|
||||
|
||||
free_filespec(spec);
|
||||
FREE_AND_NULL(ends);
|
||||
free(range_part);
|
||||
}
|
||||
|
||||
for (p = ranges; p; p = p->next)
|
||||
@ -760,15 +764,13 @@ static void parse_pathspec_from_ranges(struct pathspec *pathspec,
|
||||
{
|
||||
struct line_log_data *r;
|
||||
struct strvec array = STRVEC_INIT;
|
||||
const char **paths;
|
||||
|
||||
for (r = range; r; r = r->next)
|
||||
strvec_push(&array, r->path);
|
||||
paths = strvec_detach(&array);
|
||||
|
||||
parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", paths);
|
||||
/* strings are now owned by pathspec */
|
||||
free(paths);
|
||||
parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", array.v);
|
||||
|
||||
strvec_clear(&array);
|
||||
}
|
||||
|
||||
void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args)
|
||||
@ -781,21 +783,22 @@ void line_log_init(struct rev_info *rev, const char *prefix, struct string_list
|
||||
add_line_range(rev, commit, range);
|
||||
|
||||
parse_pathspec_from_ranges(&rev->diffopt.pathspec, range);
|
||||
|
||||
free_line_log_data(range);
|
||||
}
|
||||
|
||||
static void move_diff_queue(struct diff_queue_struct *dst,
|
||||
struct diff_queue_struct *src)
|
||||
{
|
||||
assert(src != dst);
|
||||
memcpy(dst, src, sizeof(struct diff_queue_struct));
|
||||
DIFF_QUEUE_CLEAR(src);
|
||||
memcpy(dst, src, sizeof(*dst));
|
||||
diff_queue_init(src);
|
||||
}
|
||||
|
||||
static void filter_diffs_for_paths(struct line_log_data *range, int keep_deletions)
|
||||
{
|
||||
int i;
|
||||
struct diff_queue_struct outq;
|
||||
DIFF_QUEUE_CLEAR(&outq);
|
||||
struct diff_queue_struct outq = DIFF_QUEUE_INIT;
|
||||
|
||||
for (i = 0; i < diff_queued_diff.nr; i++) {
|
||||
struct diff_filepair *p = diff_queued_diff.queue[i];
|
||||
@ -850,12 +853,12 @@ static void queue_diffs(struct line_log_data *range,
|
||||
clear_pathspec(&opt->pathspec);
|
||||
parse_pathspec_from_ranges(&opt->pathspec, range);
|
||||
}
|
||||
DIFF_QUEUE_CLEAR(&diff_queued_diff);
|
||||
diff_queue_clear(&diff_queued_diff);
|
||||
diff_tree_oid(parent_tree_oid, tree_oid, "", opt);
|
||||
if (opt->detect_rename && diff_might_be_rename()) {
|
||||
/* must look at the full tree diff to detect renames */
|
||||
clear_pathspec(&opt->pathspec);
|
||||
DIFF_QUEUE_CLEAR(&diff_queued_diff);
|
||||
diff_queue_clear(&diff_queued_diff);
|
||||
|
||||
diff_tree_oid(parent_tree_oid, tree_oid, "", opt);
|
||||
|
||||
@ -1095,7 +1098,7 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair)
|
||||
static void free_diffqueues(int n, struct diff_queue_struct *dq)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
diff_free_queue(&dq[i]);
|
||||
diff_queue_clear(&dq[i]);
|
||||
free(dq);
|
||||
}
|
||||
|
||||
@ -1130,10 +1133,18 @@ static int process_all_files(struct line_log_data **range_out,
|
||||
while (rg && strcmp(rg->path, pair->two->path))
|
||||
rg = rg->next;
|
||||
assert(rg);
|
||||
if (rg->pair)
|
||||
diff_free_filepair(rg->pair);
|
||||
rg->pair = diff_filepair_dup(queue->queue[i]);
|
||||
diff_ranges_release(&rg->diff);
|
||||
memcpy(&rg->diff, pairdiff, sizeof(struct diff_ranges));
|
||||
FREE_AND_NULL(pairdiff);
|
||||
}
|
||||
|
||||
if (pairdiff) {
|
||||
diff_ranges_release(pairdiff);
|
||||
free(pairdiff);
|
||||
}
|
||||
free(pairdiff);
|
||||
}
|
||||
|
||||
return changed;
|
||||
@ -1198,7 +1209,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c
|
||||
if (parent)
|
||||
add_line_range(rev, parent, parent_range);
|
||||
free_line_log_data(parent_range);
|
||||
diff_free_queue(&queue);
|
||||
diff_queue_clear(&queue);
|
||||
return changed;
|
||||
}
|
||||
|
||||
@ -1211,12 +1222,13 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
|
||||
struct commit_list *p;
|
||||
int i;
|
||||
int nparents = commit_list_count(commit->parents);
|
||||
int ret;
|
||||
|
||||
if (nparents > 1 && rev->first_parent_only)
|
||||
nparents = 1;
|
||||
|
||||
ALLOC_ARRAY(diffqueues, nparents);
|
||||
ALLOC_ARRAY(cand, nparents);
|
||||
CALLOC_ARRAY(cand, nparents);
|
||||
ALLOC_ARRAY(parents, nparents);
|
||||
|
||||
p = commit->parents;
|
||||
@ -1228,7 +1240,6 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
|
||||
|
||||
for (i = 0; i < nparents; i++) {
|
||||
int changed;
|
||||
cand[i] = NULL;
|
||||
changed = process_all_files(&cand[i], rev, &diffqueues[i], range);
|
||||
if (!changed) {
|
||||
/*
|
||||
@ -1236,13 +1247,10 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
|
||||
* don't follow any other path in history
|
||||
*/
|
||||
add_line_range(rev, parents[i], cand[i]);
|
||||
clear_commit_line_range(rev, commit);
|
||||
commit_list_append(parents[i], &commit->parents);
|
||||
free(parents);
|
||||
free(cand);
|
||||
free_diffqueues(nparents, diffqueues);
|
||||
/* NEEDSWORK leaking like a sieve */
|
||||
return 0;
|
||||
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1250,18 +1258,25 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
|
||||
* No single parent took the blame. We add the candidates
|
||||
* from the above loop to the parents.
|
||||
*/
|
||||
for (i = 0; i < nparents; i++) {
|
||||
for (i = 0; i < nparents; i++)
|
||||
add_line_range(rev, parents[i], cand[i]);
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
clear_commit_line_range(rev, commit);
|
||||
free(parents);
|
||||
for (i = 0; i < nparents; i++) {
|
||||
if (!cand[i])
|
||||
continue;
|
||||
line_log_data_clear(cand[i]);
|
||||
free(cand[i]);
|
||||
}
|
||||
free(cand);
|
||||
free_diffqueues(nparents, diffqueues);
|
||||
return 1;
|
||||
return ret;
|
||||
|
||||
/* NEEDSWORK evil merge detection stuff */
|
||||
/* NEEDSWORK leaking like a sieve */
|
||||
}
|
||||
|
||||
int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit *commit)
|
||||
|
@ -675,7 +675,7 @@ static void show_diff_of_diff(struct rev_info *opt)
|
||||
struct diff_queue_struct dq;
|
||||
|
||||
memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));
|
||||
DIFF_QUEUE_CLEAR(&diff_queued_diff);
|
||||
diff_queue_init(&diff_queued_diff);
|
||||
|
||||
fprintf_ln(opt->diffopt.file, "\n%s", opt->idiff_title);
|
||||
show_interdiff(opt->idiff_oid1, opt->idiff_oid2, 2,
|
||||
@ -694,7 +694,7 @@ static void show_diff_of_diff(struct rev_info *opt)
|
||||
};
|
||||
|
||||
memcpy(&dq, &diff_queued_diff, sizeof(diff_queued_diff));
|
||||
DIFF_QUEUE_CLEAR(&diff_queued_diff);
|
||||
diff_queue_init(&diff_queued_diff);
|
||||
|
||||
fprintf_ln(opt->diffopt.file, "\n%s", opt->rdiff_title);
|
||||
/*
|
||||
|
@ -3536,7 +3536,7 @@ simple_cleanup:
|
||||
/* Free memory for renames->pairs[] and combined */
|
||||
for (s = MERGE_SIDE1; s <= MERGE_SIDE2; s++) {
|
||||
free(renames->pairs[s].queue);
|
||||
DIFF_QUEUE_CLEAR(&renames->pairs[s]);
|
||||
diff_queue_init(&renames->pairs[s]);
|
||||
}
|
||||
for (i = 0; i < combined.nr; i++)
|
||||
pool_diff_free_filepair(&opt->priv->pool, combined.queue[i]);
|
||||
|
@ -649,7 +649,7 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
|
||||
struct write_midx_context *ctx)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
const char *tmp_file;
|
||||
char *tmp_file;
|
||||
|
||||
trace2_region_enter("midx", "write_midx_reverse_index", the_repository);
|
||||
|
||||
@ -662,6 +662,7 @@ static void write_midx_reverse_index(char *midx_name, unsigned char *midx_hash,
|
||||
die(_("cannot store reverse index file"));
|
||||
|
||||
strbuf_release(&buf);
|
||||
free(tmp_file);
|
||||
|
||||
trace2_region_leave("midx", "write_midx_reverse_index", the_repository);
|
||||
}
|
||||
@ -1445,6 +1446,8 @@ static int write_midx_internal(const char *object_dir,
|
||||
return -1;
|
||||
}
|
||||
|
||||
strbuf_release(&final_midx_name);
|
||||
|
||||
keep_hashes[ctx.num_multi_pack_indexes_before] =
|
||||
xstrdup(hash_to_hex(midx_hash));
|
||||
|
||||
|
@ -64,6 +64,12 @@ static void free_pseudo_merge_commit_idx(struct pseudo_merge_commit_idx *idx)
|
||||
free(idx);
|
||||
}
|
||||
|
||||
static void pseudo_merge_group_release_cb(void *payload, const char *name UNUSED)
|
||||
{
|
||||
pseudo_merge_group_release(payload);
|
||||
free(payload);
|
||||
}
|
||||
|
||||
void bitmap_writer_free(struct bitmap_writer *writer)
|
||||
{
|
||||
uint32_t i;
|
||||
@ -82,6 +88,8 @@ void bitmap_writer_free(struct bitmap_writer *writer)
|
||||
kh_foreach_value(writer->pseudo_merge_commits, idx,
|
||||
free_pseudo_merge_commit_idx(idx));
|
||||
kh_destroy_oid_map(writer->pseudo_merge_commits);
|
||||
string_list_clear_func(&writer->pseudo_merge_groups,
|
||||
pseudo_merge_group_release_cb);
|
||||
|
||||
for (i = 0; i < writer->selected_nr; i++) {
|
||||
struct bitmapped_commit *bc = &writer->selected[i];
|
||||
@ -905,6 +913,7 @@ static void write_pseudo_merges(struct bitmap_writer *writer,
|
||||
for (i = 0; i < writer->pseudo_merges_nr; i++)
|
||||
bitmap_free(commits_bitmap[i]);
|
||||
|
||||
oid_array_clear(&commits);
|
||||
free(pseudo_merge_ofs);
|
||||
free(commits_bitmap);
|
||||
}
|
||||
|
@ -1390,8 +1390,8 @@ static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
|
||||
}
|
||||
|
||||
base = bitmap_new();
|
||||
if (!cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap))
|
||||
bitmap_free(roots_bitmap);
|
||||
cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap);
|
||||
bitmap_free(roots_bitmap);
|
||||
}
|
||||
|
||||
/*
|
||||
|
42
pack-write.c
42
pack-write.c
@ -213,15 +213,15 @@ static void write_rev_trailer(struct hashfile *f, const unsigned char *hash)
|
||||
hashwrite(f, hash, the_hash_algo->rawsz);
|
||||
}
|
||||
|
||||
const char *write_rev_file(const char *rev_name,
|
||||
struct pack_idx_entry **objects,
|
||||
uint32_t nr_objects,
|
||||
const unsigned char *hash,
|
||||
unsigned flags)
|
||||
char *write_rev_file(const char *rev_name,
|
||||
struct pack_idx_entry **objects,
|
||||
uint32_t nr_objects,
|
||||
const unsigned char *hash,
|
||||
unsigned flags)
|
||||
{
|
||||
uint32_t *pack_order;
|
||||
uint32_t i;
|
||||
const char *ret;
|
||||
char *ret;
|
||||
|
||||
if (!(flags & WRITE_REV) && !(flags & WRITE_REV_VERIFY))
|
||||
return NULL;
|
||||
@ -239,13 +239,14 @@ const char *write_rev_file(const char *rev_name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *write_rev_file_order(const char *rev_name,
|
||||
uint32_t *pack_order,
|
||||
uint32_t nr_objects,
|
||||
const unsigned char *hash,
|
||||
unsigned flags)
|
||||
char *write_rev_file_order(const char *rev_name,
|
||||
uint32_t *pack_order,
|
||||
uint32_t nr_objects,
|
||||
const unsigned char *hash,
|
||||
unsigned flags)
|
||||
{
|
||||
struct hashfile *f;
|
||||
char *path;
|
||||
int fd;
|
||||
|
||||
if ((flags & WRITE_REV) && (flags & WRITE_REV_VERIFY))
|
||||
@ -255,12 +256,13 @@ const char *write_rev_file_order(const char *rev_name,
|
||||
if (!rev_name) {
|
||||
struct strbuf tmp_file = STRBUF_INIT;
|
||||
fd = odb_mkstemp(&tmp_file, "pack/tmp_rev_XXXXXX");
|
||||
rev_name = strbuf_detach(&tmp_file, NULL);
|
||||
path = strbuf_detach(&tmp_file, NULL);
|
||||
} else {
|
||||
unlink(rev_name);
|
||||
fd = xopen(rev_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
|
||||
path = xstrdup(rev_name);
|
||||
}
|
||||
f = hashfd(fd, rev_name);
|
||||
f = hashfd(fd, path);
|
||||
} else if (flags & WRITE_REV_VERIFY) {
|
||||
struct stat statbuf;
|
||||
if (stat(rev_name, &statbuf)) {
|
||||
@ -271,22 +273,24 @@ const char *write_rev_file_order(const char *rev_name,
|
||||
die_errno(_("could not stat: %s"), rev_name);
|
||||
}
|
||||
f = hashfd_check(rev_name);
|
||||
} else
|
||||
path = xstrdup(rev_name);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
write_rev_header(f);
|
||||
|
||||
write_rev_index_positions(f, pack_order, nr_objects);
|
||||
write_rev_trailer(f, hash);
|
||||
|
||||
if (rev_name && adjust_shared_perm(rev_name) < 0)
|
||||
die(_("failed to make %s readable"), rev_name);
|
||||
if (adjust_shared_perm(path) < 0)
|
||||
die(_("failed to make %s readable"), path);
|
||||
|
||||
finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
|
||||
CSUM_HASH_IN_STREAM | CSUM_CLOSE |
|
||||
((flags & WRITE_IDX_VERIFY) ? 0 : CSUM_FSYNC));
|
||||
|
||||
return rev_name;
|
||||
return path;
|
||||
}
|
||||
|
||||
static void write_mtimes_header(struct hashfile *f)
|
||||
@ -550,7 +554,7 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
|
||||
unsigned char hash[],
|
||||
char **idx_tmp_name)
|
||||
{
|
||||
const char *rev_tmp_name = NULL;
|
||||
char *rev_tmp_name = NULL;
|
||||
char *mtimes_tmp_name = NULL;
|
||||
|
||||
if (adjust_shared_perm(pack_tmp_name))
|
||||
@ -576,7 +580,7 @@ void stage_tmp_packfiles(struct strbuf *name_buffer,
|
||||
if (mtimes_tmp_name)
|
||||
rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes");
|
||||
|
||||
free((char *)rev_tmp_name);
|
||||
free(rev_tmp_name);
|
||||
free(mtimes_tmp_name);
|
||||
}
|
||||
|
||||
|
4
pack.h
4
pack.h
@ -96,8 +96,8 @@ struct ref;
|
||||
|
||||
void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought);
|
||||
|
||||
const char *write_rev_file(const char *rev_name, struct pack_idx_entry **objects, uint32_t nr_objects, const unsigned char *hash, unsigned flags);
|
||||
const char *write_rev_file_order(const char *rev_name, uint32_t *pack_order, uint32_t nr_objects, const unsigned char *hash, unsigned flags);
|
||||
char *write_rev_file(const char *rev_name, struct pack_idx_entry **objects, uint32_t nr_objects, const unsigned char *hash, unsigned flags);
|
||||
char *write_rev_file_order(const char *rev_name, uint32_t *pack_order, uint32_t nr_objects, const unsigned char *hash, unsigned flags);
|
||||
|
||||
/*
|
||||
* The "hdr" output buffer should be at least this big, which will handle sizes
|
||||
|
@ -87,7 +87,7 @@ static void pseudo_merge_group_init(struct pseudo_merge_group *group)
|
||||
{
|
||||
memset(group, 0, sizeof(struct pseudo_merge_group));
|
||||
|
||||
strmap_init_with_options(&group->matches, NULL, 0);
|
||||
strmap_init_with_options(&group->matches, NULL, 1);
|
||||
|
||||
group->decay = DEFAULT_PSEUDO_MERGE_DECAY;
|
||||
group->max_merges = DEFAULT_PSEUDO_MERGE_MAX_MERGES;
|
||||
@ -97,6 +97,25 @@ static void pseudo_merge_group_init(struct pseudo_merge_group *group)
|
||||
group->stable_size = DEFAULT_PSEUDO_MERGE_STABLE_SIZE;
|
||||
}
|
||||
|
||||
void pseudo_merge_group_release(struct pseudo_merge_group *group)
|
||||
{
|
||||
struct hashmap_iter iter;
|
||||
struct strmap_entry *e;
|
||||
|
||||
regfree(group->pattern);
|
||||
free(group->pattern);
|
||||
|
||||
strmap_for_each_entry(&group->matches, &iter, e) {
|
||||
struct pseudo_merge_matches *matches = e->value;
|
||||
free(matches->stable);
|
||||
free(matches->unstable);
|
||||
free(matches);
|
||||
}
|
||||
strmap_clear(&group->matches, 0);
|
||||
|
||||
free(group->merges);
|
||||
}
|
||||
|
||||
static int pseudo_merge_config(const char *var, const char *value,
|
||||
const struct config_context *ctx,
|
||||
void *cb_data)
|
||||
@ -256,7 +275,7 @@ static int find_pseudo_merge_group_for_ref(const char *refname,
|
||||
matches = strmap_get(&group->matches, group_name.buf);
|
||||
if (!matches) {
|
||||
matches = xcalloc(1, sizeof(*matches));
|
||||
strmap_put(&group->matches, strbuf_detach(&group_name, NULL),
|
||||
strmap_put(&group->matches, group_name.buf,
|
||||
matches);
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,8 @@ struct pseudo_merge_group {
|
||||
timestamp_t stable_threshold;
|
||||
};
|
||||
|
||||
void pseudo_merge_group_release(struct pseudo_merge_group *group);
|
||||
|
||||
struct pseudo_merge_matches {
|
||||
struct commit **stable;
|
||||
struct commit **unstable;
|
||||
|
@ -3125,6 +3125,7 @@ out:
|
||||
if (f)
|
||||
free_hashfile(f);
|
||||
strbuf_release(&sb);
|
||||
free(eoie_c);
|
||||
free(ieot);
|
||||
return ret;
|
||||
}
|
||||
|
15
remote.c
15
remote.c
@ -868,6 +868,20 @@ struct strvec *push_url_of_remote(struct remote *remote)
|
||||
return remote->pushurl.nr ? &remote->pushurl : &remote->url;
|
||||
}
|
||||
|
||||
void ref_push_report_free(struct ref_push_report *report)
|
||||
{
|
||||
while (report) {
|
||||
struct ref_push_report *next = report->next;
|
||||
|
||||
free(report->ref_name);
|
||||
free(report->old_oid);
|
||||
free(report->new_oid);
|
||||
free(report);
|
||||
|
||||
report = next;
|
||||
}
|
||||
}
|
||||
|
||||
static int match_name_with_pattern(const char *key, const char *name,
|
||||
const char *value, char **result)
|
||||
{
|
||||
@ -1122,6 +1136,7 @@ void free_one_ref(struct ref *ref)
|
||||
if (!ref)
|
||||
return;
|
||||
free_one_ref(ref->peer_ref);
|
||||
ref_push_report_free(ref->report);
|
||||
free(ref->remote_status);
|
||||
free(ref->tracking_ref);
|
||||
free(ref->symref);
|
||||
|
4
remote.h
4
remote.h
@ -126,13 +126,15 @@ int remote_has_url(struct remote *remote, const char *url);
|
||||
struct strvec *push_url_of_remote(struct remote *remote);
|
||||
|
||||
struct ref_push_report {
|
||||
const char *ref_name;
|
||||
char *ref_name;
|
||||
struct object_id *old_oid;
|
||||
struct object_id *new_oid;
|
||||
unsigned int forced_update:1;
|
||||
struct ref_push_report *next;
|
||||
};
|
||||
|
||||
void ref_push_report_free(struct ref_push_report *);
|
||||
|
||||
struct ref {
|
||||
struct ref *next;
|
||||
struct object_id old_oid;
|
||||
|
14
revision.c
14
revision.c
@ -3250,6 +3250,7 @@ static int remove_duplicate_parents(struct rev_info *revs, struct commit *commit
|
||||
struct commit *parent = p->item;
|
||||
if (parent->object.flags & TMP_MARK) {
|
||||
*pp = p->next;
|
||||
free(p);
|
||||
if (ts)
|
||||
compact_treesame(revs, commit, surviving_parents);
|
||||
continue;
|
||||
@ -4005,6 +4006,7 @@ int rewrite_parents(struct rev_info *revs, struct commit *commit,
|
||||
break;
|
||||
case rewrite_one_noparents:
|
||||
*pp = parent->next;
|
||||
free(parent);
|
||||
continue;
|
||||
case rewrite_one_error:
|
||||
return -1;
|
||||
@ -4205,10 +4207,18 @@ static void save_parents(struct rev_info *revs, struct commit *commit)
|
||||
*pp = EMPTY_PARENT_LIST;
|
||||
}
|
||||
|
||||
static void free_saved_parent(struct commit_list **parents)
|
||||
{
|
||||
if (*parents != EMPTY_PARENT_LIST)
|
||||
free_commit_list(*parents);
|
||||
}
|
||||
|
||||
static void free_saved_parents(struct rev_info *revs)
|
||||
{
|
||||
if (revs->saved_parents_slab)
|
||||
clear_saved_parents(revs->saved_parents_slab);
|
||||
if (!revs->saved_parents_slab)
|
||||
return;
|
||||
deep_clear_saved_parents(revs->saved_parents_slab, free_saved_parent);
|
||||
FREE_AND_NULL(revs->saved_parents_slab);
|
||||
}
|
||||
|
||||
struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit)
|
||||
|
1
scalar.c
1
scalar.c
@ -732,6 +732,7 @@ static int cmd_reconfigure(int argc, const char **argv)
|
||||
succeeded = 1;
|
||||
|
||||
the_repository = old_repo;
|
||||
repo_clear(&r);
|
||||
|
||||
if (toggle_maintenance(1) >= 0)
|
||||
succeeded = 1;
|
||||
|
6
shell.c
6
shell.c
@ -143,6 +143,7 @@ static void run_shell(void)
|
||||
}
|
||||
|
||||
free(argv);
|
||||
free(split_args);
|
||||
free(rawargs);
|
||||
} while (!done);
|
||||
}
|
||||
@ -216,9 +217,8 @@ int cmd_main(int argc, const char **argv)
|
||||
count = split_cmdline(prog, &user_argv);
|
||||
if (count >= 0) {
|
||||
if (is_valid_cmd_name(user_argv[0])) {
|
||||
prog = make_cmd(user_argv[0]);
|
||||
user_argv[0] = prog;
|
||||
execv(user_argv[0], (char *const *) user_argv);
|
||||
char *cmd = make_cmd(user_argv[0]);
|
||||
execv(cmd, (char *const *) user_argv);
|
||||
}
|
||||
free(prog);
|
||||
free(user_argv);
|
||||
|
@ -901,8 +901,9 @@ static void traverse_tree_submodules(struct repository *r,
|
||||
struct submodule_tree_entry *st_entry;
|
||||
struct name_entry name_entry;
|
||||
char *tree_path = NULL;
|
||||
char *tree_buf;
|
||||
|
||||
fill_tree_descriptor(r, &tree, treeish_name);
|
||||
tree_buf = fill_tree_descriptor(r, &tree, treeish_name);
|
||||
while (tree_entry(&tree, &name_entry)) {
|
||||
if (prefix)
|
||||
tree_path =
|
||||
@ -930,6 +931,8 @@ static void traverse_tree_submodules(struct repository *r,
|
||||
&name_entry.oid, out);
|
||||
free(tree_path);
|
||||
}
|
||||
|
||||
free(tree_buf);
|
||||
}
|
||||
|
||||
void submodules_of_tree(struct repository *r,
|
||||
@ -943,6 +946,16 @@ void submodules_of_tree(struct repository *r,
|
||||
traverse_tree_submodules(r, treeish_name, NULL, treeish_name, out);
|
||||
}
|
||||
|
||||
void submodule_entry_list_release(struct submodule_entry_list *list)
|
||||
{
|
||||
for (size_t i = 0; i < list->entry_nr; i++) {
|
||||
free(list->entries[i].name_entry);
|
||||
repo_clear(list->entries[i].repo);
|
||||
free(list->entries[i].repo);
|
||||
}
|
||||
free(list->entries);
|
||||
}
|
||||
|
||||
void submodule_free(struct repository *r)
|
||||
{
|
||||
if (r->submodule_cache)
|
||||
|
@ -136,4 +136,7 @@ struct submodule_entry_list {
|
||||
void submodules_of_tree(struct repository *r,
|
||||
const struct object_id *treeish_name,
|
||||
struct submodule_entry_list *ret);
|
||||
|
||||
void submodule_entry_list_release(struct submodule_entry_list *list);
|
||||
|
||||
#endif /* SUBMODULE_CONFIG_H */
|
||||
|
@ -26,6 +26,8 @@ static void object_info(const char *gitdir, const char *oid_hex)
|
||||
if (oid_object_info_extended(&r, &oid, &oi, 0))
|
||||
die("could not obtain object info");
|
||||
printf("%d\n", (int) size);
|
||||
|
||||
repo_clear(&r);
|
||||
}
|
||||
|
||||
int cmd__partial_clone(int argc, const char **argv)
|
||||
|
@ -196,5 +196,12 @@ int cmd__proc_receive(int argc, const char **argv)
|
||||
packet_flush(1);
|
||||
sigchain_pop(SIGPIPE);
|
||||
|
||||
while (commands) {
|
||||
struct command *next = commands->next;
|
||||
free(commands);
|
||||
commands = next;
|
||||
}
|
||||
string_list_clear(&push_options, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
test_description='partial clone'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY"/lib-terminal.sh
|
||||
|
||||
|
@ -5,6 +5,7 @@ test_description='compare full workdir to sparse workdir'
|
||||
GIT_TEST_SPLIT_INDEX=0
|
||||
GIT_TEST_SPARSE_INDEX=
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
|
@ -5,6 +5,7 @@ test_description='git branch submodule 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
|
||||
|
||||
|
@ -7,6 +7,7 @@ This test runs git rebase and tests the subtree strategy.
|
||||
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
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
test_description='test {cherry-pick,revert} --[no-]gpg-sign'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY/lib-gpg.sh"
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
test_description='stash --pathspec-from-file'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_tick
|
||||
|
@ -34,6 +34,7 @@ relationship between packs and objects is as follows:
|
||||
Px2 | s s s x x x
|
||||
'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
main_repo=main.git
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
test_description='exercise basic multi-pack bitmap functionality (.rev files)'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
. "${TEST_DIRECTORY}/lib-bitmap.sh"
|
||||
|
||||
|
@ -4,6 +4,7 @@ test_description='pseudo-merge bitmaps'
|
||||
|
||||
GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_pseudo_merges () {
|
||||
|
@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='incremental multi-pack-index'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
. "$TEST_DIRECTORY"/lib-midx.sh
|
||||
|
||||
|
@ -8,6 +8,7 @@ test_description='Test proc-receive hook'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
. "$TEST_DIRECTORY"/t5411/common-functions.sh
|
||||
|
@ -8,6 +8,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1
|
||||
export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
mk_repo_pair () {
|
||||
|
@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
# Test protocol v2 with 'file://' transport
|
||||
|
@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
# Test protocol v2 with 'git://' transport
|
||||
|
@ -7,6 +7,7 @@ TEST_NO_CREATE_REPO=1
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
# Test protocol v2 with 'http://' transport
|
||||
|
@ -5,6 +5,7 @@ test_description='merge simplification'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
note () {
|
||||
|
@ -10,6 +10,7 @@ test_description='--graph and simplified history'
|
||||
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-log-graph.sh
|
||||
|
||||
|
@ -4,6 +4,7 @@ test_description='git filter-branch'
|
||||
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-gpg.sh"
|
||||
|
||||
|
@ -5,6 +5,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_CREATE_REPO_NO_TEMPLATE=1
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
PROG='git annotate'
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
test_description='test the `scalar` command'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt,launchctl:true,schtasks:true"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
test_description='test the `scalar clone` subcommand'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
. "${TEST_DIRECTORY}/lib-terminal.sh"
|
||||
|
||||
|
@ -7,6 +7,7 @@ test_description='git fast-export'
|
||||
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' '
|
||||
|
@ -11,6 +11,7 @@ cvs CLI client via git-cvsserver server'
|
||||
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; then
|
||||
|
@ -8,6 +8,7 @@ tags, branches and other git refspecs'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
#########
|
||||
|
@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='git shell tests'
|
||||
|
||||
TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'shell allows upload-pack' '
|
||||
|
@ -717,6 +717,7 @@ static int add_file_to_list(const struct object_id *oid,
|
||||
static void wt_status_collect_changes_initial(struct wt_status *s)
|
||||
{
|
||||
struct index_state *istate = s->repo->index;
|
||||
struct strbuf base = STRBUF_INIT;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < istate->cache_nr; i++) {
|
||||
@ -735,7 +736,6 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
|
||||
* expanding the trees to find the elements that are new in this
|
||||
* tree and marking them with DIFF_STATUS_ADDED.
|
||||
*/
|
||||
struct strbuf base = STRBUF_INIT;
|
||||
struct pathspec ps = { 0 };
|
||||
struct tree *tree = lookup_tree(istate->repo, &ce->oid);
|
||||
|
||||
@ -743,9 +743,11 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
|
||||
ps.has_wildcard = 1;
|
||||
ps.max_depth = -1;
|
||||
|
||||
strbuf_reset(&base);
|
||||
strbuf_add(&base, ce->name, ce->ce_namelen);
|
||||
read_tree_at(istate->repo, tree, &base, 0, &ps,
|
||||
add_file_to_list, s);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -772,6 +774,8 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
|
||||
s->committable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
strbuf_release(&base);
|
||||
}
|
||||
|
||||
static void wt_status_collect_untracked(struct wt_status *s)
|
||||
|
Loading…
Reference in New Issue
Block a user