Skip to content

Commit

Permalink
Enable the creation of transient cache entries
Browse files Browse the repository at this point in the history
Signed-off-by: Jameson Miller <jamill@microsoft.com>
  • Loading branch information
jamill authored and dscho committed Mar 29, 2018
1 parent c3a2b02 commit b662e0b
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 35 deletions.
4 changes: 2 additions & 2 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,11 @@ static int checkout_merged(int pos, const struct checkout *state)
blob_type, oid.hash))
die(_("Unable to add merge result for '%s'"), path);
free(result_buf.ptr);
ce = make_cache_entry_from_index(state->istate, mode, oid.hash, path, 2, 0);
ce = make_transient_cache_entry(mode, oid.hash, path, 2);
if (!ce)
die(_("make_cache_entry failed for path '%s'"), path);
status = checkout_entry(ce, state, NULL);
cache_entry_free(ce);
transient_cache_entry_free(ce);
return status;
}

Expand Down
22 changes: 2 additions & 20 deletions builtin/difftool.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,28 +321,10 @@ static int checkout_path(unsigned mode, struct object_id *oid,
struct cache_entry *ce;
int ret;

/*
* REVIEW: This is a transient cache entry - it is freed
* a couple lines below.
*
* We have worked to remove the ability to
* allocate individual cache entries -
* but if we know it is going to be freed,
* then maybe there is no need to allocate
* from a memory pool.
*
* For now, allocate from the_index.
*
* Options:
* 1) expect an istate to be passed in (via state)
* 2) (re)enable us to allocate an individual cache entry
* 3) work against the_index
* 4) Can we use stack allocated memory?
*/
ce = make_cache_entry_from_index(&the_index, mode, oid->hash, path, 0, 0);
ce = make_transient_cache_entry(mode, oid->hash, path, 0);
ret = checkout_entry(ce, state, NULL);

cache_entry_free(ce);
transient_cache_entry_free(ce);
return ret;
}

Expand Down
14 changes: 13 additions & 1 deletion cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,14 +716,24 @@ extern int add_to_index(struct index_state *, const char *path, struct stat *, i
extern int add_file_to_index(struct index_state *, const char *path, int flags);

extern struct cache_entry *make_cache_entry_from_index(struct index_state *, unsigned int mode, const unsigned char *sha1, const char *path, int stage, unsigned int refresh_options);
extern struct cache_entry *make_transient_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage);

/*
* Create an empty cache entry struct.
* Create an empty cache entry struct. This is intended for use with
* cache_entries that could be added to the associated index.
*
* istate: The index whose memory pool this cache entry should be allocated from.
* len: The length to reserve for the path field of the cache entry.
*/
extern struct cache_entry *make_empty_cache_entry_from_index(struct index_state *istate, size_t len);

/*
* Create an empty cache entry struct. This is intended for use with
* cache_entries that will not be added to an index.
*
* len: The length to reserve for the path field of the cache entry.
*/
extern struct cache_entry *make_empty_transient_cache_entry(size_t len);
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);
Expand Down Expand Up @@ -2000,6 +2010,8 @@ void safe_create_dir(const char *dir, int share);
extern int print_sha1_ellipsis(void);

void cache_entry_free(struct cache_entry *ce);
void transient_cache_entry_free(struct cache_entry *ce);

void validate_cache_entries(const struct index_state *istate);

#endif /* CACHE_H */
51 changes: 43 additions & 8 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,10 +781,15 @@ struct cache_entry *make_empty_cache_entry_from_index(struct index_state *istate
return mem_pool__ce_calloc(find_mem_pool(istate), len);
}

struct cache_entry *make_cache_entry_from_index(struct index_state *istate,
unsigned int mode,
const unsigned char *sha1, const char *path, int stage,
unsigned int refresh_options)
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 unsigned char *sha1, const char *path, int stage,
unsigned int refresh_options, int is_transient)
{
int len;
struct cache_entry *ce, *ret;
Expand All @@ -795,20 +800,45 @@ struct cache_entry *make_cache_entry_from_index(struct index_state *istate,
}

len = strlen(path);
ce = make_empty_cache_entry_from_index(istate, len);
ce = is_transient ? make_empty_transient_cache_entry(len) :
make_empty_cache_entry_from_index(istate, len);

hashcpy(ce->oid.hash, sha1);
memcpy(ce->name, path, len);
ce->ce_flags = create_ce_flags(stage);
ce->ce_namelen = len;
ce->ce_mode = create_ce_mode(mode);

ret = refresh_cache_entry(istate, ce, refresh_options);
if (ret != ce)
cache_entry_free(ce);
/*
* Transient cache entries cannot be refreshed - they are not associated
* with the index.
*/
if (!is_transient) {
ret = refresh_cache_entry(istate, ce, refresh_options);

if (ret != ce)
cache_entry_free(ce);
} else {
ret = ce;
}

return ret;
}

struct cache_entry *make_cache_entry_from_index(struct index_state *istate, unsigned int mode,
const unsigned char *sha1, const char *path,
int stage, unsigned int refresh_options)
{
return make_cache_entry(istate, mode, sha1, path, stage,
refresh_options, 0);
}

struct cache_entry *make_transient_cache_entry(unsigned int mode, const unsigned char *sha1,
const char *path, int stage)
{
return make_cache_entry(NULL, mode, sha1, path, stage, 0, 1);
}

/*
* Chmod an index entry with either +x or -x.
*
Expand Down Expand Up @@ -2830,3 +2860,8 @@ void cache_entry_free(struct cache_entry *ce)
if (ce && invalidate_cache_entry)
memset(ce, 0xCD, cache_entry_size(ce->ce_namelen));
}

void transient_cache_entry_free(struct cache_entry *ce)
{
free(ce);
}
12 changes: 8 additions & 4 deletions unpack-trees.c
Original file line number Diff line number Diff line change
Expand Up @@ -781,10 +781,14 @@ static int ce_in_traverse_path(const struct cache_entry *ce,
static struct cache_entry *create_ce_entry(const struct traverse_info *info,
const struct name_entry *n,
int stage,
struct index_state *istate)
struct index_state *istate,
int is_transient)
{
int len = traverse_path_len(info, n);
struct cache_entry *ce = make_empty_cache_entry_from_index(istate, len);
struct cache_entry *ce =
is_transient ?
make_empty_transient_cache_entry(len) :
make_empty_cache_entry_from_index(istate, len);

ce->ce_mode = create_ce_mode(n->mode);
ce->ce_flags = create_ce_flags(stage);
Expand Down Expand Up @@ -830,7 +834,7 @@ 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, &o->result);
src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result, o->merge);
}

if (o->merge) {
Expand All @@ -839,7 +843,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)
cache_entry_free(ce);
transient_cache_entry_free(ce);
}
return rc;
}
Expand Down

0 comments on commit b662e0b

Please sign in to comment.