Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apply.c24
-rw-r--r--blame.c5
-rw-r--r--builtin/checkout.c8
-rw-r--r--builtin/difftool.c6
-rw-r--r--builtin/reset.c2
-rw-r--r--builtin/update-index.c26
-rw-r--r--cache.h40
-rw-r--r--merge-recursive.c2
-rw-r--r--read-cache.c93
-rw-r--r--resolve-undo.c4
-rw-r--r--split-index.c8
-rw-r--r--tree.c4
-rw-r--r--unpack-trees.c35
13 files changed, 165 insertions, 92 deletions
diff --git a/apply.c b/apply.c
index 5dd634ceaf..ee6c406c7a 100644
--- a/apply.c
+++ b/apply.c
@@ -4090,12 +4090,12 @@ static int build_fake_ancestor(struct apply_state *state, struct patch *list)
return error(_("sha1 information is lacking or useless "
"(%s)."), name);
- ce = make_cache_entry(patch->old_mode, &oid, name, 0, 0);
+ ce = make_cache_entry(&result, patch->old_mode, &oid, name, 0, 0);
if (!ce)
return error(_("make_cache_entry failed for path '%s'"),
name);
if (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD)) {
- free(ce);
+ discard_cache_entry(ce);
return error(_("could not add %s to temporary index"),
name);
}
@@ -4263,12 +4263,11 @@ static int add_index_file(struct apply_state *state,
struct stat st;
struct cache_entry *ce;
int namelen = strlen(path);
- unsigned ce_size = cache_entry_size(namelen);
if (!state->update_index)
return 0;
- ce = xcalloc(1, ce_size);
+ ce = make_empty_cache_entry(&the_index, namelen);
memcpy(ce->name, path, namelen);
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = create_ce_flags(0);
@@ -4278,13 +4277,13 @@ static int add_index_file(struct apply_state *state,
if (!skip_prefix(buf, "Subproject commit ", &s) ||
get_oid_hex(s, &ce->oid)) {
- free(ce);
- return error(_("corrupt patch for submodule %s"), path);
+ discard_cache_entry(ce);
+ return error(_("corrupt patch for submodule %s"), path);
}
} else {
if (!state->cached) {
if (lstat(path, &st) < 0) {
- free(ce);
+ discard_cache_entry(ce);
return error_errno(_("unable to stat newly "
"created file '%s'"),
path);
@@ -4292,13 +4291,13 @@ static int add_index_file(struct apply_state *state,
fill_stat_cache_info(ce, &st);
}
if (write_object_file(buf, size, blob_type, &ce->oid) < 0) {
- free(ce);
+ discard_cache_entry(ce);
return error(_("unable to create backing store "
"for newly created file %s"), path);
}
}
if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {
- free(ce);
+ discard_cache_entry(ce);
return error(_("unable to add cache entry for %s"), path);
}
@@ -4422,27 +4421,26 @@ static int add_conflicted_stages_file(struct apply_state *state,
struct patch *patch)
{
int stage, namelen;
- unsigned ce_size, mode;
+ unsigned mode;
struct cache_entry *ce;
if (!state->update_index)
return 0;
namelen = strlen(patch->new_name);
- ce_size = cache_entry_size(namelen);
mode = patch->new_mode ? patch->new_mode : (S_IFREG | 0644);
remove_file_from_cache(patch->new_name);
for (stage = 1; stage < 4; stage++) {
if (is_null_oid(&patch->threeway_stage[stage - 1]))
continue;
- ce = xcalloc(1, ce_size);
+ ce = make_empty_cache_entry(&the_index, namelen);
memcpy(ce->name, patch->new_name, namelen);
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = create_ce_flags(stage);
ce->ce_namelen = namelen;
oidcpy(&ce->oid, &patch->threeway_stage[stage - 1]);
if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0) {
- free(ce);
+ discard_cache_entry(ce);
return error(_("unable to add cache entry for %s"),
patch->new_name);
}
diff --git a/blame.c b/blame.c
index 14d0e0b575..4c6668d0e1 100644
--- a/blame.c
+++ b/blame.c
@@ -154,7 +154,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
struct strbuf buf = STRBUF_INIT;
const char *ident;
time_t now;
- int size, len;
+ int len;
struct cache_entry *ce;
unsigned mode;
struct strbuf msg = STRBUF_INIT;
@@ -252,8 +252,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
/* Let's not bother reading from HEAD tree */
mode = S_IFREG | 0644;
}
- size = cache_entry_size(len);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(&the_index, len);
oidcpy(&ce->oid, &origin->blob_oid);
memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(0);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 548bf40f25..56d1e1a28d 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -77,7 +77,7 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
return READ_TREE_RECURSIVE;
len = base->len + strlen(pathname);
- ce = xcalloc(1, cache_entry_size(len));
+ ce = make_empty_cache_entry(&the_index, len);
oidcpy(&ce->oid, oid);
memcpy(ce->name, base->buf, base->len);
memcpy(ce->name + base->len, pathname, len - base->len);
@@ -96,7 +96,7 @@ static int update_some(const struct object_id *oid, struct strbuf *base,
if (ce->ce_mode == old->ce_mode &&
!oidcmp(&ce->oid, &old->oid)) {
old->ce_flags |= CE_UPDATE;
- free(ce);
+ discard_cache_entry(ce);
return 0;
}
}
@@ -230,11 +230,11 @@ static int checkout_merged(int pos, const struct checkout *state)
if (write_object_file(result_buf.ptr, result_buf.size, blob_type, &oid))
die(_("Unable to add merge result for '%s'"), path);
free(result_buf.ptr);
- ce = make_cache_entry(mode, &oid, path, 2, 0);
+ ce = make_transient_cache_entry(mode, &oid, path, 2);
if (!ce)
die(_("make_cache_entry failed for path '%s'"), path);
status = checkout_entry(ce, state, NULL);
- free(ce);
+ discard_cache_entry(ce);
return status;
}
diff --git a/builtin/difftool.c b/builtin/difftool.c
index 873a06f0d9..4593f0c2cd 100644
--- a/builtin/difftool.c
+++ b/builtin/difftool.c
@@ -321,10 +321,10 @@ static int checkout_path(unsigned mode, struct object_id *oid,
struct cache_entry *ce;
int ret;
- ce = make_cache_entry(mode, oid, path, 0, 0);
+ ce = make_transient_cache_entry(mode, oid, path, 0);
ret = checkout_entry(ce, state, NULL);
- free(ce);
+ discard_cache_entry(ce);
return ret;
}
@@ -488,7 +488,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
* index.
*/
struct cache_entry *ce2 =
- make_cache_entry(rmode, &roid,
+ make_cache_entry(&wtindex, rmode, &roid,
dst_path, 0, 0);
add_index_entry(&wtindex, ce2,
diff --git a/builtin/reset.c b/builtin/reset.c
index 00109b041f..c3f0cfa1e8 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -134,7 +134,7 @@ static void update_index_from_diff(struct diff_queue_struct *q,
continue;
}
- ce = make_cache_entry(one->mode, &one->oid, one->path,
+ ce = make_cache_entry(&the_index, one->mode, &one->oid, one->path,
0, 0);
if (!ce)
die(_("make_cache_entry failed for path '%s'"),
diff --git a/builtin/update-index.c b/builtin/update-index.c
index a8709a26ec..ea2f2a476c 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -268,15 +268,14 @@ static int process_lstat_error(const char *path, int err)
static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st)
{
- int option, size;
+ int option;
struct cache_entry *ce;
/* Was the old index entry already up-to-date? */
if (old && !ce_stage(old) && !ce_match_stat(old, st, 0))
return 0;
- size = cache_entry_size(len);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(&the_index, len);
memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(0);
ce->ce_namelen = len;
@@ -285,13 +284,13 @@ static int add_one_path(const struct cache_entry *old, const char *path, int len
if (index_path(&ce->oid, path, st,
info_only ? 0 : HASH_WRITE_OBJECT)) {
- free(ce);
+ discard_cache_entry(ce);
return -1;
}
option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
if (add_cache_entry(ce, option)) {
- free(ce);
+ discard_cache_entry(ce);
return error("%s: cannot add to the index - missing --add option?", path);
}
return 0;
@@ -402,15 +401,14 @@ static int process_path(const char *path, struct stat *st, int stat_errno)
static int add_cacheinfo(unsigned int mode, const struct object_id *oid,
const char *path, int stage)
{
- int size, len, option;
+ int len, option;
struct cache_entry *ce;
if (!verify_path(path, mode))
return error("Invalid path '%s'", path);
len = strlen(path);
- size = cache_entry_size(len);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(&the_index, len);
oidcpy(&ce->oid, oid);
memcpy(ce->name, path, len);
@@ -599,7 +597,6 @@ static struct cache_entry *read_one_ent(const char *which,
{
unsigned mode;
struct object_id oid;
- int size;
struct cache_entry *ce;
if (get_tree_entry(ent, path, &oid, &mode)) {
@@ -612,8 +609,7 @@ static struct cache_entry *read_one_ent(const char *which,
error("%s: not a blob in %s branch.", path, which);
return NULL;
}
- size = cache_entry_size(namelen);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(&the_index, namelen);
oidcpy(&ce->oid, &oid);
memcpy(ce->name, path, namelen);
@@ -690,8 +686,8 @@ static int unresolve_one(const char *path)
error("%s: cannot add their version to the index.", path);
ret = -1;
free_return:
- free(ce_2);
- free(ce_3);
+ discard_cache_entry(ce_2);
+ discard_cache_entry(ce_3);
return ret;
}
@@ -758,7 +754,7 @@ static int do_reupdate(int ac, const char **av,
ce->name, ce_namelen(ce), 0);
if (old && ce->ce_mode == old->ce_mode &&
!oidcmp(&ce->oid, &old->oid)) {
- free(old);
+ discard_cache_entry(old);
continue; /* unchanged */
}
/* Be careful. The working tree may not have the
@@ -769,7 +765,7 @@ static int do_reupdate(int ac, const char **av,
path = xstrdup(ce->name);
update_one(path);
free(path);
- free(old);
+ discard_cache_entry(old);
if (save_nr != active_nr)
goto redo;
}
diff --git a/cache.h b/cache.h
index 7953d52caa..5aadaebaeb 100644
--- a/cache.h
+++ b/cache.h
@@ -339,6 +339,40 @@ extern void remove_name_hash(struct index_state *istate, struct cache_entry *ce)
extern void free_name_hash(struct index_state *istate);
+/* Cache entry creation and cleanup */
+
+/*
+ * Create cache_entry intended for use in the specified index. Caller
+ * is responsible for discarding the cache_entry with
+ * `discard_cache_entry`.
+ */
+struct cache_entry *make_cache_entry(struct index_state *istate,
+ unsigned int mode,
+ const struct object_id *oid,
+ const char *path,
+ int stage,
+ unsigned int refresh_options);
+
+struct cache_entry *make_empty_cache_entry(struct index_state *istate,
+ size_t name_len);
+
+/*
+ * Create a cache_entry that is not intended to be added to an index.
+ * Caller is responsible for discarding the cache_entry
+ * with `discard_cache_entry`.
+ */
+struct cache_entry *make_transient_cache_entry(unsigned int mode,
+ const struct object_id *oid,
+ const char *path,
+ int stage);
+
+struct cache_entry *make_empty_transient_cache_entry(size_t name_len);
+
+/*
+ * Discard cache entry.
+ */
+void discard_cache_entry(struct cache_entry *ce);
+
#ifndef NO_THE_INDEX_COMPATIBILITY_MACROS
#define active_cache (the_index.cache)
#define active_nr (the_index.cache_nr)
@@ -698,12 +732,6 @@ extern int remove_file_from_index(struct index_state *, const char *path);
extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags);
extern int add_file_to_index(struct index_state *, const char *path, int flags);
-extern struct cache_entry *make_cache_entry(unsigned int mode,
- const struct object_id *oid,
- const char *path,
- int stage,
- unsigned int refresh_options);
-
extern int chmod_index_entry(struct index_state *, struct cache_entry *ce, char flip);
extern int ce_same_name(const struct cache_entry *a, const struct cache_entry *b);
extern void set_object_name_for_intent_to_add_entry(struct cache_entry *ce);
diff --git a/merge-recursive.c b/merge-recursive.c
index 8b30cc7e35..a580cff886 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -315,7 +315,7 @@ static int add_cacheinfo(struct merge_options *o,
struct cache_entry *ce;
int ret;
- ce = make_cache_entry(mode, oid ? oid : &null_oid, path, stage, 0);
+ ce = make_cache_entry(&the_index, mode, oid ? oid : &null_oid, path, stage, 0);
if (!ce)
return err(o, _("add_cacheinfo failed for path '%s'; merge aborting."), path);
diff --git a/read-cache.c b/read-cache.c
index c12664c789..41e4d0e67a 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -61,7 +61,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
replace_index_entry_in_base(istate, old, ce);
remove_name_hash(istate, old);
- free(old);
+ discard_cache_entry(old);
ce->ce_flags &= ~CE_HASHED;
set_index_entry(istate, nr, ce);
ce->ce_flags |= CE_UPDATE_IN_BASE;
@@ -74,7 +74,7 @@ void rename_index_entry_at(struct index_state *istate, int nr, const char *new_n
struct cache_entry *old_entry = istate->cache[nr], *new_entry;
int namelen = strlen(new_name);
- new_entry = xmalloc(cache_entry_size(namelen));
+ new_entry = make_empty_cache_entry(istate, namelen);
copy_cache_entry(new_entry, old_entry);
new_entry->ce_flags &= ~CE_HASHED;
new_entry->ce_namelen = namelen;
@@ -623,7 +623,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate,
/* Ok, create the new entry using the name of the existing alias */
len = ce_namelen(alias);
- new_entry = xcalloc(1, cache_entry_size(len));
+ new_entry = make_empty_cache_entry(istate, len);
memcpy(new_entry->name, alias->name, len);
copy_cache_entry(new_entry, ce);
save_or_free_index_entry(istate, ce);
@@ -640,7 +640,7 @@ void set_object_name_for_intent_to_add_entry(struct cache_entry *ce)
int add_to_index(struct index_state *istate, const char *path, struct stat *st, int flags)
{
- int size, namelen, was_same;
+ int namelen, was_same;
mode_t st_mode = st->st_mode;
struct cache_entry *ce, *alias = NULL;
unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE|CE_MATCH_RACY_IS_DIRTY;
@@ -662,8 +662,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
while (namelen && path[namelen-1] == '/')
namelen--;
}
- size = cache_entry_size(namelen);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(istate, namelen);
memcpy(ce->name, path, namelen);
ce->ce_namelen = namelen;
if (!intent_only)
@@ -704,13 +703,13 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
ce_mark_uptodate(alias);
alias->ce_flags |= CE_ADDED;
- free(ce);
+ discard_cache_entry(ce);
return 0;
}
}
if (!intent_only) {
if (index_path(&ce->oid, path, st, newflags)) {
- free(ce);
+ discard_cache_entry(ce);
return error("unable to index file %s", path);
}
} else
@@ -727,9 +726,9 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
ce->ce_mode == alias->ce_mode);
if (pretend)
- free(ce);
+ discard_cache_entry(ce);
else if (add_index_entry(istate, ce, add_option)) {
- free(ce);
+ discard_cache_entry(ce);
return error("unable to add %s to index", path);
}
if (verbose && !was_same)
@@ -745,14 +744,25 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
return add_to_index(istate, path, &st, flags);
}
-struct cache_entry *make_cache_entry(unsigned int mode,
+struct cache_entry *make_empty_cache_entry(struct index_state *istate, size_t len)
+{
+ return xcalloc(1, cache_entry_size(len));
+}
+
+struct cache_entry *make_empty_transient_cache_entry(size_t len)
+{
+ return xcalloc(1, cache_entry_size(len));
+}
+
+struct cache_entry *make_cache_entry(struct index_state *istate,
+ unsigned int mode,
const struct object_id *oid,
const char *path,
int stage,
unsigned int refresh_options)
{
- int size, len;
struct cache_entry *ce, *ret;
+ int len;
if (!verify_path(path, mode)) {
error("Invalid path '%s'", path);
@@ -760,8 +770,7 @@ struct cache_entry *make_cache_entry(unsigned int mode,
}
len = strlen(path);
- size = cache_entry_size(len);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(istate, len);
oidcpy(&ce->oid, oid);
memcpy(ce->name, path, len);
@@ -771,10 +780,33 @@ struct cache_entry *make_cache_entry(unsigned int mode,
ret = refresh_cache_entry(&the_index, ce, refresh_options);
if (ret != ce)
- free(ce);
+ discard_cache_entry(ce);
return ret;
}
+struct cache_entry *make_transient_cache_entry(unsigned int mode, const struct object_id *oid,
+ const char *path, int stage)
+{
+ struct cache_entry *ce;
+ int len;
+
+ if (!verify_path(path, mode)) {
+ error("Invalid path '%s'", path);
+ return NULL;
+ }
+
+ len = strlen(path);
+ ce = make_empty_transient_cache_entry(len);
+
+ oidcpy(&ce->oid, oid);
+ memcpy(ce->name, path, len);
+ ce->ce_flags = create_ce_flags(stage);
+ ce->ce_namelen = len;
+ ce->ce_mode = create_ce_mode(mode);
+
+ return ce;
+}
+
/*
* Chmod an index entry with either +x or -x.
*
@@ -1270,7 +1302,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
{
struct stat st;
struct cache_entry *updated;
- int changed, size;
+ int changed;
int refresh = options & CE_MATCH_REFRESH;
int ignore_valid = options & CE_MATCH_IGNORE_VALID;
int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
@@ -1350,8 +1382,7 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
return NULL;
}
- size = ce_size(ce);
- updated = xmalloc(size);
+ updated = make_empty_cache_entry(istate, ce_namelen(ce));
copy_cache_entry(updated, ce);
memcpy(updated->name, ce->name, ce->ce_namelen + 1);
fill_stat_cache_info(updated, &st);
@@ -1637,12 +1668,13 @@ int read_index(struct index_state *istate)
return read_index_from(istate, get_index_file(), get_git_dir());
}
-static struct cache_entry *cache_entry_from_ondisk(struct ondisk_cache_entry *ondisk,
+static struct cache_entry *cache_entry_from_ondisk(struct index_state *istate,
+ struct ondisk_cache_entry *ondisk,
unsigned int flags,
const char *name,
size_t len)
{
- struct cache_entry *ce = xmalloc(cache_entry_size(len));
+ struct cache_entry *ce = make_empty_cache_entry(istate, len);
ce->ce_stat_data.sd_ctime.sec = get_be32(&ondisk->ctime.sec);
ce->ce_stat_data.sd_mtime.sec = get_be32(&ondisk->mtime.sec);
@@ -1684,7 +1716,8 @@ static unsigned long expand_name_field(struct strbuf *name, const char *cp_)
return (const char *)ep + 1 - cp_;
}
-static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk,
+static struct cache_entry *create_from_disk(struct index_state *istate,
+ struct ondisk_cache_entry *ondisk,
unsigned long *ent_size,
struct strbuf *previous_name)
{
@@ -1715,13 +1748,13 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk,
/* v3 and earlier */
if (len == CE_NAMEMASK)
len = strlen(name);
- ce = cache_entry_from_ondisk(ondisk, flags, name, len);
+ ce = cache_entry_from_ondisk(istate, ondisk, flags, name, len);
*ent_size = ondisk_ce_size(ce);
} else {
unsigned long consumed;
consumed = expand_name_field(previous_name, name);
- ce = cache_entry_from_ondisk(ondisk, flags,
+ ce = cache_entry_from_ondisk(istate, ondisk, flags,
previous_name->buf,
previous_name->len);
@@ -1853,7 +1886,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
unsigned long consumed;
disk_ce = (struct ondisk_cache_entry *)((char *)mmap + src_offset);
- ce = create_from_disk(disk_ce, &consumed, previous_name);
+ ce = create_from_disk(istate, disk_ce, &consumed, previous_name);
set_index_entry(istate, i, ce);
src_offset += consumed;
@@ -1959,7 +1992,7 @@ int discard_index(struct index_state *istate)
istate->cache[i]->index <= istate->split_index->base->cache_nr &&
istate->cache[i] == istate->split_index->base->cache[istate->cache[i]->index - 1])
continue;
- free(istate->cache[i]);
+ discard_cache_entry(istate->cache[i]);
}
resolve_undo_clear_index(istate);
istate->cache_nr = 0;
@@ -2649,14 +2682,13 @@ int read_index_unmerged(struct index_state *istate)
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i];
struct cache_entry *new_ce;
- int size, len;
+ int len;
if (!ce_stage(ce))
continue;
unmerged = 1;
len = ce_namelen(ce);
- size = cache_entry_size(len);
- new_ce = xcalloc(1, size);
+ new_ce = make_empty_cache_entry(istate, len);
memcpy(new_ce->name, ce->name, len);
new_ce->ce_flags = create_ce_flags(0) | CE_CONFLICTED;
new_ce->ce_namelen = len;
@@ -2765,3 +2797,8 @@ void move_index_extensions(struct index_state *dst, struct index_state *src)
dst->untracked = src->untracked;
src->untracked = NULL;
}
+
+void discard_cache_entry(struct cache_entry *ce)
+{
+ free(ce);
+}
diff --git a/resolve-undo.c b/resolve-undo.c
index 4d4e5cb6bf..c30ae5cf49 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -146,7 +146,9 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
struct cache_entry *nce;
if (!ru->mode[i])
continue;
- nce = make_cache_entry(ru->mode[i], &ru->oid[i],
+ nce = make_cache_entry(istate,
+ ru->mode[i],
+ &ru->oid[i],
name, i + 1, 0);
if (matched)
nce->ce_flags |= CE_MATCHED;
diff --git a/split-index.c b/split-index.c
index 660c75f31f..317900db8b 100644
--- a/split-index.c
+++ b/split-index.c
@@ -123,7 +123,7 @@ static void replace_entry(size_t pos, void *data)
src->ce_flags |= CE_UPDATE_IN_BASE;
src->ce_namelen = dst->ce_namelen;
copy_cache_entry(dst, src);
- free(src);
+ discard_cache_entry(src);
si->nr_replacements++;
}
@@ -224,7 +224,7 @@ void prepare_to_write_split_index(struct index_state *istate)
base->ce_flags = base_flags;
if (ret)
ce->ce_flags |= CE_UPDATE_IN_BASE;
- free(base);
+ discard_cache_entry(base);
si->base->cache[ce->index - 1] = ce;
}
for (i = 0; i < si->base->cache_nr; i++) {
@@ -301,7 +301,7 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce
ce == istate->split_index->base->cache[ce->index - 1])
ce->ce_flags |= CE_REMOVE;
else
- free(ce);
+ discard_cache_entry(ce);
}
void replace_index_entry_in_base(struct index_state *istate,
@@ -314,7 +314,7 @@ void replace_index_entry_in_base(struct index_state *istate,
old_entry->index <= istate->split_index->base->cache_nr) {
new_entry->index = old_entry->index;
if (old_entry != istate->split_index->base->cache[new_entry->index - 1])
- free(istate->split_index->base->cache[new_entry->index - 1]);
+ discard_cache_entry(istate->split_index->base->cache[new_entry->index - 1]);
istate->split_index->base->cache[new_entry->index - 1] = new_entry;
}
}
diff --git a/tree.c b/tree.c
index 244eb5e665..5111ce8376 100644
--- a/tree.c
+++ b/tree.c
@@ -16,15 +16,13 @@ static int read_one_entry_opt(struct index_state *istate,
unsigned mode, int stage, int opt)
{
int len;
- unsigned int size;
struct cache_entry *ce;
if (S_ISDIR(mode))
return READ_TREE_RECURSIVE;
len = strlen(pathname);
- size = cache_entry_size(baselen + len);
- ce = xcalloc(1, size);
+ ce = make_empty_cache_entry(istate, baselen + len);
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = create_ce_flags(stage);
diff --git a/unpack-trees.c b/unpack-trees.c
index 3a85a02a77..33cba550b0 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -203,10 +203,10 @@ static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
ADD_CACHE_OK_TO_ADD | ADD_CACHE_OK_TO_REPLACE);
}
-static struct cache_entry *dup_entry(const struct cache_entry *ce)
+static struct cache_entry *dup_entry(const struct cache_entry *ce, struct index_state *istate)
{
unsigned int size = ce_size(ce);
- struct cache_entry *new_entry = xmalloc(size);
+ struct cache_entry *new_entry = make_empty_cache_entry(istate, ce_namelen(ce));
memcpy(new_entry, ce, size);
return new_entry;
@@ -216,7 +216,7 @@ static void add_entry(struct unpack_trees_options *o,
const struct cache_entry *ce,
unsigned int set, unsigned int clear)
{
- do_add_entry(o, dup_entry(ce), set, clear);
+ do_add_entry(o, dup_entry(ce, &o->result), set, clear);
}
/*
@@ -797,10 +797,17 @@ static int ce_in_traverse_path(const struct cache_entry *ce,
return (info->pathlen < ce_namelen(ce));
}
-static struct cache_entry *create_ce_entry(const struct traverse_info *info, const struct name_entry *n, int stage)
+static struct cache_entry *create_ce_entry(const struct traverse_info *info,
+ const struct name_entry *n,
+ int stage,
+ struct index_state *istate,
+ int is_transient)
{
int len = traverse_path_len(info, n);
- struct cache_entry *ce = xcalloc(1, cache_entry_size(len));
+ struct cache_entry *ce =
+ is_transient ?
+ make_empty_transient_cache_entry(len) :
+ make_empty_cache_entry(istate, len);
ce->ce_mode = create_ce_mode(n->mode);
ce->ce_flags = create_ce_flags(stage);
@@ -846,7 +853,15 @@ static int unpack_nondirectories(int n, unsigned long mask,
stage = 3;
else
stage = 2;
- src[i + o->merge] = create_ce_entry(info, names + i, stage);
+
+ /*
+ * If the merge bit is set, then the cache entries are
+ * discarded in the following block. In this case,
+ * construct "transient" cache_entries, as they are
+ * not stored in the index. otherwise construct the
+ * cache entry from the index aware logic.
+ */
+ src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result, o->merge);
}
if (o->merge) {
@@ -855,7 +870,7 @@ static int unpack_nondirectories(int n, unsigned long mask,
for (i = 0; i < n; i++) {
struct cache_entry *ce = src[i + o->merge];
if (ce != o->df_conflict_entry)
- free(ce);
+ discard_cache_entry(ce);
}
return rc;
}
@@ -1787,7 +1802,7 @@ static int merged_entry(const struct cache_entry *ce,
struct unpack_trees_options *o)
{
int update = CE_UPDATE;
- struct cache_entry *merge = dup_entry(ce);
+ struct cache_entry *merge = dup_entry(ce, &o->result);
if (!old) {
/*
@@ -1807,7 +1822,7 @@ static int merged_entry(const struct cache_entry *ce,
if (verify_absent(merge,
ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN, o)) {
- free(merge);
+ discard_cache_entry(merge);
return -1;
}
invalidate_ce_path(merge, o);
@@ -1833,7 +1848,7 @@ static int merged_entry(const struct cache_entry *ce,
update = 0;
} else {
if (verify_uptodate(old, o)) {
- free(merge);
+ discard_cache_entry(merge);
return -1;
}
/* Migrate old flags over */