diff options
author | Junio C Hamano <gitster@pobox.com> | 2017-09-19 10:47:55 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-09-19 10:47:55 +0900 |
commit | 09595ab3818619a34281b85e1fb98802182e12a2 (patch) | |
tree | 6f4074659713f2370682b7fc5c46d4e81573d60d /builtin/reset.c | |
parent | df80c5760c947f2013df86f52d0a5103d07958a2 (diff) | |
parent | 0e5bba53af7d6f911e99589d736cdf06badad0fe (diff) | |
download | git-09595ab3818619a34281b85e1fb98802182e12a2.tar.gz |
Merge branch 'jk/leak-checkers'
Many of our programs consider that it is OK to release dynamic
storage that is used throughout the life of the program by simply
exiting, but this makes it harder to leak detection tools to avoid
reporting false positives. Plug many existing leaks and introduce
a mechanism for developers to mark that the region of memory
pointed by a pointer is not lost/leaking to help these tools.
* jk/leak-checkers:
add UNLEAK annotation for reducing leak false positives
set_git_dir: handle feeding gitdir to itself
repository: free fields before overwriting them
reset: free allocated tree buffers
reset: make tree counting less confusing
config: plug user_config leak
update-index: fix cache entry leak in add_one_file()
add: free leaked pathspec after add_files_to_cache()
test-lib: set LSAN_OPTIONS to abort by default
test-lib: --valgrind should not override --verbose-log
Diffstat (limited to 'builtin/reset.c')
-rw-r--r-- | builtin/reset.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/builtin/reset.c b/builtin/reset.c index f1af9345e4..9cd89b2305 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -44,10 +44,11 @@ static inline int is_merge(void) static int reset_index(const struct object_id *oid, int reset_type, int quiet) { - int nr = 1; + int i, nr = 0; struct tree_desc desc[2]; struct tree *tree; struct unpack_trees_options opts; + int ret = -1; memset(&opts, 0, sizeof(opts)); opts.head_idx = 1; @@ -75,23 +76,32 @@ static int reset_index(const struct object_id *oid, int reset_type, int quiet) struct object_id head_oid; if (get_oid("HEAD", &head_oid)) return error(_("You do not have a valid HEAD.")); - if (!fill_tree_descriptor(desc, &head_oid)) + if (!fill_tree_descriptor(desc + nr, &head_oid)) return error(_("Failed to find tree of HEAD.")); nr++; opts.fn = twoway_merge; } - if (!fill_tree_descriptor(desc + nr - 1, oid)) - return error(_("Failed to find tree of %s."), oid_to_hex(oid)); + if (!fill_tree_descriptor(desc + nr, oid)) { + error(_("Failed to find tree of %s."), oid_to_hex(oid)); + goto out; + } + nr++; + if (unpack_trees(nr, desc, &opts)) - return -1; + goto out; if (reset_type == MIXED || reset_type == HARD) { tree = parse_tree_indirect(oid); prime_cache_tree(&the_index, tree); } - return 0; + ret = 0; + +out: + for (i = 0; i < nr; i++) + free((void *)desc[i].buffer); + return ret; } static void print_new_head_line(struct commit *commit) |